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中修复了这个问题。现在, sourceViewController
和destinationViewController
正确地声明为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) } } }