2015-10-05 78 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

相關問題