使用UIStoryboardSegue自定义UIViewController的演示过渡

最受欢迎的方式是 UIViewControllerAnimatedTransitioning

为了做到这一点,你必须:

  • 新建一个子类,该子类可称为 “XXXTransitioning”,继承自 “NSObject”,并实现协议 “UIViewControllerAnimatedTransitioning “的两个功能。
1
2
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
  • Then:
    1. 在 “ViewController “中新建一个 “XXXTransitioning “的实例。
    2. 设置transitioningDelegate = self
    3. 用 UIViewControllerTransitioningDelegate 扩展 “ViewController”,并实现。
1
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?

dismiss

我注意到 Storyboard Segue 有一个 Custom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class XXXModalSegue: UIStoryboardSegue {
override func perform() {
let fromVC = source
let toVC = destination

let fromView = fromVC.view!
let toView = toVC.view!

let (w, h) = (UIScreen.main.bounds.width, UIScreen.main.bounds.height)

toView.alpha = 0
toView.frame = CGRect(x: w/2, y: 0, width: w, height: h)

let window = UIApplication.shared.keyWindow
window?.insertSubview(toView, aboveSubview: fromView)

UIView.animate(withDuration: 0.4, animations: {
toView.alpha = 1
toView.frame = toView.frame.offsetBy(dx: -w/2, dy: 0)
}) { (b) in

self.source.present(self.destination, animated: false, completion: nil)
// OR: self.source.dismiss(animated: false, completion: nil)
s
}
}

就是这样,不用再编码delegateExtension。简单又干净:)