@objc(SEPushNoAnimationSegue) class SEPushNoAnimationSegue: UIStoryboardSegue { override func perform () { self.sourceViewController.navigationController.pushViewController(self.destinationViewController, animated:false) } }
Dans le code ci-dessus, j'ai 2 questions: 1). il a une erreur de compilation: 'UINavigationController!' n'a pas de membre nommé 'pushViewController'
Mais dans cette class, il a fait une méthode pushViewController.
2). Je dois append l'annotation: @objc (SEPushNoAnimationSegue), sinon, dans le storyboard, il ne reconnaît que le nom généré randomment, comme, _tcxxxxSEPushNoAnimationSegue.
pourquoi ces 2 problèmes se produisent ici?
UIStoryboardSegue a un défaut irritant: ses propriétés sourceViewController et destinationViewController sont tapées comme AnyObject!
(c'est le cas même dans Objective-C (type d'ID)) et non comme UIViewController
, comme il se doit.
Ce même défaut crée des ravages dans votre code parfait et simple. Voici comment le réécrire afin de corriger les erreurs de compilation:
@objc(SEPushNoAnimationSegue) class SEPushNoAnimationSegue: UIStoryboardSegue { override func perform () { let src = self.sourceViewController as UIViewController let dst = self.destinationViewController as UIViewController src.navigationController.pushViewController(dst, animated:false) } }
REMARQUE: Apple a corrigé cette sourceViewController
dans iOS 9. sourceViewController
et destinationViewController
sont maintenant correctement déclarés comme UIViewController
.
Le compilateur Swift stocke ses symboles en utilisant son propre nom mangling , et le bon vieux 'Objective-C ne le reconnaît pas dans Xcode. L'utilisation d'un @obj()
explicite résout le problème.
Cela fonctionne bien pour moi
@objc(SEPushNoAnimationSegue) class SEPushNoAnimationSegue: UIStoryboardSegue { override func perform() { let sourceViewController = self.sourceViewController as UIViewController let destinationViewController = self.destinationViewController as UIViewController sourceViewController.presentViewController(destinationViewController, animated: true, completion: nil) } }
Encore mieux:
import UIKit class CustomSegue: UIStoryboardSegue { override func perform() { self.sourceViewController.presentViewController(self.destinationViewController as UIViewController, animated: false, completion: nil) } }
Swift 3.0:
import UIKit class CustomNoAnimationSegue: UIStoryboardSegue { override func perform() { if let navigation = source.navigationController { navigation.pushViewController(destination, animated: false) } } }