Swift中的自定义Segue

use*_*913 15 ios swift ios8

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

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

但是在那个类中,它确实有一个pushViewController方法.

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

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

Jea*_*nan 33

问题#1

UIStoryboardSegue有一个令人恼火的缺陷:它的sourceViewController和destinationViewController属性被输入AnyObject!(即使在Objective-C(Id类型)中也是如此)而不是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)
    }
}
Run Code Online (Sandbox Code Playgroud)

注:苹果在iOS中9固定这个东西sourceViewControllerdestinationViewController现在被正确声明为UIViewController.

问题#2

Swift编译器使用自己的名称mangling来存储它的符号,并且好的'Objective-C在Xcode中无法识别它.使用显式@obj()解决问题.

  • 明确的@objc() - 伟大的建议 - 这就是为我做的 (4认同)
  • 我无法相信只是在类声明前添加@objc(classname)才能使它工作......*facepalm* (2认同)

fab*_*ian 5

这对我来说很好

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

}
Run Code Online (Sandbox Code Playgroud)