iOS 9 中的自定义 UIViewController 转换错误
Custom UIViewController transition bug in iOS 9
我遇到了一个奇怪的错误。我只是将 iOS 的自定义转换方法用于 UIViewControllers
,使用 UIViewControllerTransitioningDelegate
以及 UIViewControllerAnimatedTransitioning
的实现。一切似乎都很好,直到我完全执行以下操作:
- 打开应用程序
- 使用我的自定义转换呈现另一个视图控制器
- 旋转为横向
- 关闭刚刚显示的视图控制器
就是这样!现在发生的情况如下:我在初始视图控制器的右侧看到一个大黑条(好像该控制器的视图没有旋转到横向)。
有趣的是,这只在 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
添加到层次结构,因为它已经存在。
我遇到了一个奇怪的错误。我只是将 iOS 的自定义转换方法用于 UIViewControllers
,使用 UIViewControllerTransitioningDelegate
以及 UIViewControllerAnimatedTransitioning
的实现。一切似乎都很好,直到我完全执行以下操作:
- 打开应用程序
- 使用我的自定义转换呈现另一个视图控制器
- 旋转为横向
- 关闭刚刚显示的视图控制器
就是这样!现在发生的情况如下:我在初始视图控制器的右侧看到一个大黑条(好像该控制器的视图没有旋转到横向)。
有趣的是,这只在 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
添加到层次结构,因为它已经存在。