iOS9中将转场动画和ViewController剥离,可以自定义Segue,从而复用.
Segues默认有几种方式:
- Show: 从Navigation Controller push一个页面.
- Show Detail: 向上弹出一个新的页面.
- Present Modally: 在当前页面覆盖一个新的页面.
- Popover: iPad弹出个小界面iPhone全屏以Model形式弹出一个界面.
- Custom:自定义Segue
关于不同Segue的区别和用法可以参考这里 那里和最后这篇
iOS8中已经不建议使用以前Segue的Push Modal Popover和Replace了.
我们要来创建一个如下图的转场效果:
Segue有三个重要的协议:
- UIViewControllerTransitioningDelegate
- UIViewControllerAnimatedTransitioning
- UIViewControllerContextTransitioning
我们创建一个ScaleSegue文件:
class ScaleSegue: UIStoryboardSegue {
override func perform() {
destinationViewController.transitioningDelegate = self
super.perform()
}
}
定义转场动画:
extension ScaleSegue: UIViewControllerTransitioningDelegate {
func animationControllerForPresentedController(presented: UIViewController,
presentingController presenting: UIViewController,
sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return ScalePresentAnimator()
}
}
class ScalePresentAnimator: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 2.0
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
var fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
if let fromNC = fromViewController as? UINavigationController {
if let controller = fromNC.topViewController {
fromViewController = controller
}
}
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)
if let toView = toView {
transitionContext.containerView()?.addSubview(toView)
}
var startFrame = CGRect.zero
if let fromViewController = fromViewController as? ViewScaleable {
startFrame = fromViewController.scaleView.frame
} else {
print("Warning: Controller \(fromViewController) does not conform to ViewScaleable")
}
toView?.frame = startFrame
toView?.layoutIfNeeded()
let duration = transitionDuration(transitionContext)
let finalFrame = transitionContext.finalFrameForViewController(toViewController)
UIView.animateWithDuration(duration, animations: {
toView?.frame = finalFrame
toView?.layoutIfNeeded()
fromView?.alpha = 0.0
}, completion: {
finished in
fromView?.alpha = 1.0
transitionContext.completeTransition(true)
})
}
最后设置下Segue class:
Girl学iOS100天 第2天
阅读和写出来果然不太一样,现在写的很费劲,没多少内容,但却花费了3个番茄钟的时间,而且质量不高,但希望自己能坚持.
很喜欢《卖油翁》的一句话"无他'唯手熟尔",共勉 :)