2015-10-05 77 views
2

我已经通过实施在UIViewControllerTransitioningDelegate协议的方法创建了一个模态视图控制器的自定义过渡动画不被调用。UIViewControllerTransitioningDelegate方法在IOS 7

在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]; 

回答

2

在呈现视图控制器的初始化剂代替viewDidLoad方法解决了该问题设置transitioningDelegate

似乎在IOS 7的视图控制器的转变逻辑viewDidLoad之前调用,但是其他的方式从iOS 8的起周围。

37

如果有人遇到这种在以后的岁月里,和你用斯威夫特3,请确保您的通话为“animationControllerForPresentedController”。

从Xcode 8.1开始,编译器不会自动识别此问题,因此不会将代码转换为现代语法。

上面的代码会编译,但它不会是一个协议实现。它将只是一个定制,未调用的函数。 (这些都是可选的协议方法危害,并与Xcode的自动完成的诸多问题。)

所以,一定要实现与斯威夫特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 
+0

非常感谢!为什么Xcode不提示原来的方法是错误的。 –

+1

谢谢!在这一个浪费时间。 – Jessica

+0

Omg。谢谢。 – chrismanderson

2

另一个问题是transitioningDelegate is a weak property。因此,您可以分配给它,然后在转换有机会运行之前让您的转换委派类为发布。当转换确实运行时,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,则会遇到此问题。这就是为什么像this one这样的教程通常需要在视图控制器类本身或作为扩展实现转换委托。其他的事情是让视图控制器不被释放。

一般来说,在Cocoa Touch中,名为“... Delegate”的任何东西都将是一个弱财产,以帮助避免保留周期。你应该使自己的自定义类委托属性也很弱。在苹果的Cocoa Core Competencies中有很好的一节。

+0

在我的问题的第二个代码块中,你会看到我已经介绍了这一点,我有一个自定义的强大属性来保存对我的转换委托的引用。然而,这可能会绊倒其他人,所以谢谢你的贡献。 :) – commscheck

+0

啊,你是对的,我错过了。 – bcattle

相关问题