Swift中的自定义Segue

时间:2014-06-12 13:12:55

标签: ios swift ios8

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

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

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

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

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

4 个答案:

答案 0 :(得分: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)
    }
}

注意:Apple在iOS 9中修复此问题。sourceViewControllerdestinationViewController现已正确声明为UIViewController

问题#2

Swift编译器使用自己的name mangling来存储它的符号,而且好的' Objective-C在Xcode中无法识别它。使用明确的@obj()解决了这个问题。

答案 1 :(得分: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)
}

}

答案 2 :(得分:1)

更好:

import UIKit

class CustomSegue: UIStoryboardSegue {
    override func perform() {
        self.sourceViewController.presentViewController(self.destinationViewController as UIViewController, animated: false, completion: nil)
    }
}

答案 3 :(得分:0)

Swift 3.0:

import UIKit

class CustomNoAnimationSegue: UIStoryboardSegue {

    override func perform() {
        if let navigation = source.navigationController {
            navigation.pushViewController(destination, animated: false)
        }
    }
}