Swift中的自定义Segue

@objc(SEPushNoAnimationSegue) class SEPushNoAnimationSegue: UIStoryboardSegue { override func perform () { self.sourceViewController.navigationController.pushViewController(self.destinationViewController, animated:false) } } 

在上面的代码中,我有两个问题:1)。 它有一个编译错误:'UINavigationController!' 没有名为“pushViewController”的成员

但在那个类中,它有一个pushViewController方法。

2)。 我必须添加注释:@objc(SEPushNoAnimationSegue),否则,在故事板中,它只识别随机生成的名称,如_tcxxxxSEPushNoAnimationSegue。

为什么这两个问题在这里发生?

问题#1

UIStoryboardSegue有一个恼人的缺陷:它的sourceViewController和destinationViewController属性的types为AnyObject! (即使在Objective-C(Idtypes)中也是如此),而不是像UIViewController那样。

同样的缺陷造成你的完美和简单的代码破坏。 以下是如何重写它以解决编译错误:

 @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) } } 

注意:Apple在iOS 9中修复了这个问题。现在, sourceViewControllerdestinationViewController正确地声明为UIViewController

问题#2

Swift编译器使用自己的名字来存储它的符号,好的“Objective-C”在Xcode中不能识别它。 使用明确的@obj()解决了这个问题。

这对我来说很好

 @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) } } 

更好:

 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) } } }