iOS 9 中的自定义 UIViewController 转换错误

Custom UIViewController transition bug in iOS 9

我遇到了一个奇怪的错误。我只是将 iOS 的自定义转换方法用于 UIViewControllers,使用 UIViewControllerTransitioningDelegate 以及 UIViewControllerAnimatedTransitioning 的实现。一切似乎都很好,直到我完全执行以下操作:

  1. 打开应用程序
  2. 使用我的自定义转换呈现另一个视图控制器
  3. 旋转为横向
  4. 关闭刚刚显示的视图控制器

就是这样!现在发生的情况如下:我在初始视图控制器的右侧看到一个大黑条(好像该控制器的视图没有旋转到横向)。

有趣的是,这只在 iOS 9 中出错,在 iOS 8 中似乎一切正常。我不知道自定义转换 API 有什么变化吗?或者这只是一个非常讨厌的 iOS 9 错误?如果有人能告诉我我做错了什么,或者如果有人能为我提供解决方法,我将不胜感激!

这些 类 重现问题:

import UIKit
class ViewController: UIViewController, UIViewControllerTransitioningDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tap")
        view.addGestureRecognizer(tapGestureRecognizer)
    }

    func tap() {
        let controller = ModalViewController()
        controller.transitioningDelegate = self
        presentViewController(controller, animated: true, completion: nil)
    }

    func animationControllerForPresentedController(presented: UIViewController,
                                                   presentingController presenting: UIViewController,
                                                   sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return Transitioning()
    }

    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return Transitioning()
    }
}

呈现的视图控制器:

import UIKit
class ModalViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor.redColor()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tap")
        view.addGestureRecognizer(tapGestureRecognizer)
    }

    func tap() {
        dismissViewControllerAnimated(true, completion: nil)
    }
}

最后 UIViewControllerAnimatedTransitioning 实施:

import UIKit
class Transitioning: NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 0.5
    }

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)
        let containerView = transitionContext.containerView()
        if let fromView = fromView, toView = toView {
            containerView?.addSubview(fromView)
            containerView?.addSubview(toView)

            toView.alpha = 0
            UIView.animateWithDuration(0.5, animations: {
                toView.alpha = 1
            }, completion: {
                finished in
                transitionContext.completeTransition(true)
            })
        }
    }
}

我一般在animateTransition中使用如下:

toView.frame = fromView.frame

仅供参考,您不必将 fromView 添加到层次结构,因为它已经存在。