Instantly share code, notes, and snippets.
Created
February 11, 2015 16:24
-
Star
(1)
1
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save okmr-d/f8141631ecb385425c32 to your computer and use it in GitHub Desktop.
Drawer Menu (iOS8〜)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// DOViewControllerWithSideBar.swift | |
// DOViewControllerWithSideBar | |
// | |
// Created by Daiki Okumura on 2015/02/11. | |
// Copyright (c) 2015 Daiki Okumura. All rights reserved. | |
// | |
import UIKit | |
class DOViewControllerWithSideBar: UIViewController, UIViewControllerTransitioningDelegate { | |
// MARK: UIViewControllerTransitioningDelegate | |
// このメソッドを実装することで、presentViewController:animated:completion:を実行するときの振る舞いに UIPresentationControllerの実装クラス(CustomPresentationController)が適用される。 | |
func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController!, sourceViewController source: UIViewController) -> UIPresentationController? { | |
let isRightBar:Bool = (presented.title == "RightBar") | |
println(isRightBar) | |
return DOSideBarPresentationController(presentedViewController: presented, presentingViewController: presenting, isRightBar: isRightBar) | |
} | |
// アニメーションは UIViewControllerAnimatedTransitioning の実装クラスを使うと書き換えることができる。 | |
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
let isRightBar:Bool = (presented.title == "RightBar") | |
println(isRightBar) | |
return DOAnimatedTransitioning(isRightBar: isRightBar, isPresent: true) | |
} | |
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
let isRightBar:Bool = (dismissed.title == "RightBar") | |
println(isRightBar) | |
return DOAnimatedTransitioning(isRightBar: isRightBar, isPresent: false) | |
} | |
} | |
class DOSideBarPresentationController: UIPresentationController { | |
// 呼び出し元のViewControllerの上に重ねるオーバーレイView | |
var overlayView: UIView! | |
let isRightBar: Bool | |
let presentedViewFrame: CGRect | |
init(presentedViewController: UIViewController!, presentingViewController: UIViewController!, isRightBar: Bool) { | |
self.isRightBar = isRightBar | |
self.presentedViewFrame = presentedViewController.view.frame | |
super.init(presentedViewController: presentedViewController, presentingViewController: presentingViewController) | |
} | |
// 表示トランジション開始前に呼ばれる | |
override func presentationTransitionWillBegin() { | |
// オーバーレイViewの設定 | |
self.overlayView = UIView(frame: self.containerView.bounds) | |
self.overlayView.gestureRecognizers = [UITapGestureRecognizer(target: self, action: "overlayDidTouch:")] | |
self.overlayView.backgroundColor = UIColor.blackColor() | |
self.overlayView.alpha = 0.0 | |
self.containerView.insertSubview(self.overlayView, atIndex: 0) | |
// トランジションを実行 | |
self.presentedViewController.transitionCoordinator()?.animateAlongsideTransition({ | |
[unowned self] context in | |
self.overlayView.alpha = 0.2 | |
}, completion: nil) | |
} | |
// 非表示トランジション開始前に呼ばれる | |
override func dismissalTransitionWillBegin() { | |
// トランジションを実行 | |
self.presentedViewController.transitionCoordinator()?.animateAlongsideTransition({ | |
[unowned self] context in | |
self.overlayView.alpha = 0.0 | |
}, completion: nil) | |
} | |
// 非表示トランジション終了後に呼ばれる | |
override func dismissalTransitionDidEnd(completed: Bool) { | |
if completed { | |
self.overlayView.removeFromSuperview() | |
} | |
} | |
// 子のコンテナのサイズを返す | |
override func sizeForChildContentContainer(container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize { | |
return self.presentedViewFrame.size | |
} | |
// 呼び出し先のViewControllerのFrame(表示トランジション後)を返す | |
override func frameOfPresentedViewInContainerView() -> CGRect { | |
return self.presentedViewFrame | |
} | |
// レイアウト開始前に呼ばれる | |
override func containerViewWillLayoutSubviews() { | |
self.overlayView.frame = self.containerView.bounds | |
self.presentedView().frame = self.frameOfPresentedViewInContainerView() | |
} | |
// レイアウト開始後に呼ばれる | |
override func containerViewDidLayoutSubviews() { | |
} | |
// オーバーレイの View をタッチしたときに呼ばれる | |
func overlayDidTouch(sender: AnyObject) { | |
self.presentedViewController.dismissViewControllerAnimated(true, completion: nil) | |
} | |
} | |
class DOAnimatedTransitioning: NSObject, UIViewControllerAnimatedTransitioning { | |
let isRightBar: Bool | |
let isPresent: Bool | |
init(isRightBar: Bool, isPresent: Bool) { | |
self.isRightBar = isRightBar | |
self.isPresent = isPresent | |
} | |
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { | |
return 0.4 | |
} | |
func animateTransition(transitionContext: UIViewControllerContextTransitioning) { | |
if isPresent { | |
presentAnimateTransition(transitionContext) | |
} else { | |
dissmissAnimateTransition(transitionContext) | |
} | |
} | |
// MARK: Custom | |
func presentAnimateTransition(transitionContext: UIViewControllerContextTransitioning) { | |
// 呼び出し元ViewController | |
let presentingController: UIViewController! = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) | |
// 呼び出し先ViewController | |
let presentedController: UIViewController! = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) | |
// コンテナView 呼び出し先ViewControllerを指定した呼び出し元ViewControllerの背後に追加します。 | |
let containerView: UIView! = transitionContext.containerView() | |
containerView.insertSubview(presentedController.view, belowSubview: presentingController.view) | |
// アニメーション | |
UIView.animateWithDuration( | |
self.transitionDuration(transitionContext), | |
animations: { | |
presentedController.view.frame.origin.x = self.isRightBar ? -presentedController.view.frame.width : presentedController.view.frame.width | |
}, | |
completion: { | |
finished in | |
transitionContext.completeTransition(true) | |
}) | |
} | |
func dissmissAnimateTransition(transitionContext: UIViewControllerContextTransitioning) { | |
// 呼び出し先ViewController | |
let presentedController: UIViewController! = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) | |
// コンテナView | |
let containerView: UIView! = transitionContext.containerView() | |
// アニメーション | |
UIView.animateWithDuration( | |
self.transitionDuration(transitionContext), | |
animations: { | |
presentedController.view.frame.origin.x = self.isRightBar ? containerView.bounds.size.width : -presentedController.view.frame.size.width | |
}, | |
completion: { | |
finished in | |
transitionContext.completeTransition(true) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment