web-dev-qa-db-ja.com

カスタムセグエSwift

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

上記のコードでは、2つの質問があります:1)。コンパイルエラーがあります: 'UINavigationController!' 'pushViewController'という名前のメンバーがありません

しかし、そのクラスでは、pushViewControllerメソッドがありました。

2)。注釈を追加する必要があります:@objc(SEPushNoAnimationSegue)、そうでない場合、ストーリーボードでは、_tcxxxxSEPushNoAnimationSegueのようにランダムに生成された名前のみが認識されます。

なぜこれらの2つの問題がここで発生するのですか?

15
user2909913

問題#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 iOS9でこの問題を修正しました。sourceViewControllerdestinationViewControllerUIViewControllerとして正しく宣言されるようになりました。

第2号

Swiftコンパイラは独自の 名前マングリング を使用してシンボルを格納し、古き良きObjective-CはXcodeでそれを認識しません。明示的な@obj()を使用する問題を解決します。

33
Jean Le Moignan

これは私にとってはうまくいきます

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

}
5
fabian

さらに良い:

import UIKit

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

Swift 3.0:

import UIKit

class CustomNoAnimationSegue: UIStoryboardSegue {

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