在iOS 7中不调用UIViewControllerTransitioningDelegate方法
我通过实现UIViewControllerTransitioningDelegate
协议中的方法为模式视图控制器创build了自定义的过渡animation。
在iOS 8和9中,这些方法通常被调用并且转换工作。 但是,在iOS 7中, animationControllerForPresentedController:presentingController:sourceController:
方法永远不会被调用。 animationControllerForDismissedController:
方法仍然正常调用。
#import "MyModalTransitioningDelegate.h" #import "MyModalFadeTransition.h" @implementation MyModalTransitioningDelegate - (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { return [[MyModalFadeTransition alloc] init]; } - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { return [[MyModalFadeTransition alloc] init]; } @end
在模式视图控制器(即“呈现的控制器”),我有以下在它的-viewDidLoad
方法:
self.modalTransitionDelegate = [[OTModalTransitioningDelegate alloc] init]; // This is a custom strong private property due to `tranisitioningDelegate` being a weak property. self.transitioningDelegate = self.modalTransitionDelegate; self.modalPresentationStyle = UIModalPresentationCustom;
设置modalPresentationStyle
在iOS的任何版本中似乎没有任何区别。 没有被调用的方法确实说它在iOS 7中可用,所以我不知道为什么它不被调用。
模态视图控制器在呈现视图控制器中呈现以下代码:
[self presentViewController:self.modalViewController animated:YES completion:nil];
如果任何人在晚些时候遇到这个,并且你正在使用Swift 3,请确保你的调用不是 “ animationControllerForPresentedController
”。
从Xcode 8.1开始,编译器不会自动识别这个问题,因此不会将代码转换为现代语法。
上面的代码将被编译,但不会是一个协议实现。 这将只是一个自定义的 ,未被调用的函数。 (这是可选协议方法的危害,以及Xcode自动完成的无数问题。)
所以,确保你用Swift 3语法来实现协议:
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { // ... return your cached controller object here. }
并记住要设置视图控制器上的演示文稿样式:
self.modalPresentationStyle = .custom
和代表:
self.transitioningDelegate = self // or wherever
在呈现视图控制器的初始化程序而不是viewDidLoad
方法中设置transitioningDelegate
修复了问题。
它出现在iOS 7中,视图控制器的转换逻辑在viewDidLoad
之前被调用,但是从iOS 8开始反过来。
另一个问题是, transitioningDelegate
是一个弱财产 。 所以你可以分配它,然后在转换有机会运行之前释放你的转换委托类。 当过渡运行时,transitioningDelegate的值是nil
,并且你的方法永远不会被调用。
要查看此信息,请执行以下操作:
let myVC = UIViewController(nibName: nil, bundle: nil) likesVC.transitioningDelegate = BackgroundFadesInPresentationDelegate(viewController: likesVC) likesVC.modalPresentationStyle = .custom present(likesVC, animated: true, completion: nil)
然后在你的转换委托类中添加
deinit { print("deinit") }
看看这个打印语句是否在转换之前被击中。
如果您使用独立类来实现UIViewControllerTransitioningDelegate
则会遇到此问题。 这就是为什么像这样的教程通常需要在视图控制器类本身或作为扩展实现转换委托。 其他的事情是让视图控制器得到释放。
一般来说,在Cocoa Touch中,任何名为“… Delegate”的东西都是一个弱的属性,有助于避免保留周期。 您应该使自己的自定义类委托属性也很弱。 在苹果的cocoa核心能力方面,有一个很好的部分。
- 如何限制在UITextField除点和下划线以外的特殊字符?
- 在Xcode 6 beta 4(iOS 8)中,为什么Core Data不会像在iOS 7中声明的那样将UIImage字段保留到后端,当我声明它是Transformable时?
- XCTest UItesting:在表格单元格中找不到collectionView
- Swift 3 – 调整字体大小以适应宽度,多行
- OpenGL ES 2.0顶点转换algorithm
- 从UITableView删除最后一行 – 崩溃与NSInternalInconsistencyError
- 如何在Swift中处理NSUserDefaults中的非可选值
- 如何委托工作和委托工作stream程在Objective-C
- iOS – 照片的背景上传