iOS-Swiftを使用してプログラムでセグメンテーションする方法


185

Facebook SDKを使用してユーザーを認証するアプリを作成しています。Facebookのロジックを別のクラスに統合しようとしています。以下にコードを示します(簡単にするために取り除いています)。

import Foundation

class FBManager {
    class func fbSessionStateChane(fbSession:FBSession!, fbSessionState:FBSessionState, error:NSError?){
        //... handling all session states
        FBRequestConnection.startForMeWithCompletionHandler { (conn: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in

            println("Logged in user: \n\(result)");

            let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
            let loggedInView: UserViewController = storyboard.instantiateViewControllerWithIdentifier("loggedInView") as UserViewController

            loggedInView.result = result;

            //todo: segue to the next view???
        }
    }
}

上記のクラスメソッドを使用してセッション状態の変化を確認していますが、問題なく動作します。

Q:ユーザーのデータを取得したら、このカスタムクラス内から次のビューにセグメンテーションするにはどうすればよいですか?

編集:明確にするために、ストーリーボードに識別子付きのセグエがあり、ビューコントローラではないクラスからセグエを実行する方法を見つけようとしています


2
好きperformSegue:
2014

はい、しかしコードはviewControllerにありません、どうすればこれを達成できますか?
Shlomi Schwartz 2014

さて、その場合は、その作業(セグエイング)を、完了したオブジェクトからビューコントローラーに(完了ブロックまたはデリゲートメソッドを介して)委任する必要があります。
2014

nil以外のレイアウト例外が発生
Chris Hayes

回答:


340

セグエがストーリーボードに存在し、2つのビューの間にセグエ識別子が存在する場合は、次のようにプログラムで呼び出すことができます。

performSegue(withIdentifier: "mySegueID", sender: nil)

古いバージョンの場合:

performSegueWithIdentifier("mySegueID", sender: nil)

あなたも行うことができます:

presentViewController(nextViewController, animated: true, completion: nil)

または、ナビゲーションコントローラを使用している場合:

self.navigationController?.pushViewController(nextViewController, animated: true)

7
返信をありがとう、ビューではないカスタムクラスからどのようにしてperformSegueWithIdentifierを呼び出すことができますか?
Shlomi Schwartz 2014

2
2番目の方法を使用する場合。データを次のビューに渡す方法は?
iamprem 2015

2
func prepareForSegue(segue:UIStoryboardSegue、sender:AnyObject?)を使用して、プロパティを設定します。
ロイドサージェント

1
performSequeWithIdentifer()を呼び出すと、呼び出し側コントローラーのprepareForSeque()の実装が呼び出され、そこにさまざまなデータを渡すことができます。実際、prepareForSeque()で受け取った送信者パラメーターは、単に送信者パラメーターに渡されたものですperformSequeWithIdentifier()
timbo 2015年

1
セグエがストーリーボードに存在しない場合はどうなりますか?たとえば、ViewController自体にセグエを作成する場合はどうでしょうか。
scaryguy

20

NSNotificationを使用できます

カスタムクラスにpostメソッドを追加します。

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

ViewControllerにオブザーバーを追加します。

NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)

ViewControllerに関数を追加します。

func methodOFReceivedNotication(notification: NSNotification){
    self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
}

1
このような通知を乱用しないでください。デリゲートを使用して、ビューコントローラーとクラス間の接続を明示的にします。複数のサブスクライバーが存在する可能性があり、インスタンスは自由にサブスクライブ/サブスクライブ解除できるため、通知の制御フローを監視することはほぼ不可能です。
uliwitness

17

セグエが2つのビューの間にセグエ識別子を持つストーリーボードに存在する場合は、プログラムを使用してそれを呼び出すことができます

self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)

ナビゲーションコントローラを使用している場合

let viewController = YourViewController(nibName: "YourViewController", bundle: nil)        
self.navigationController?.pushViewController(viewController, animated: true)

ナビゲーションコントローラーを使用した2番目のアプローチをお勧めします。


self.performSegue(withIdentifier: "yourIdentifierInStoryboard"、sender:self)
Rajneesh071

14

次のようにセグエを使用できます。

self.performSegueWithIdentifier("push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if segue.identifier == "push" {

    }
}

返信ありがとうございます。ただし、performSegueWithIdentifierはviewControllerメソッドであり、私のコードは外部クラスで実行されます
Shlomi Schwartz

13

Swift 3 - SpriteKitでも動作します

NSNotificationを使用できます。

例:

1.)ストーリーボードにセグエを作成し、識別子に「segue」という名前を付けます

2.)セグメンテーション元のViewControllerに関数を作成します。

func goToDifferentView() {

    self.performSegue(withIdentifier: "segue", sender: self)

}

3.)ViewControllerのViewDidLoad()で、オブザーバーの作成を偽装しています。

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: "segue" as NSNotification.Name, object: nil)

更新 -前回これを使用したときは.addObserver、次のコードの呼び出しを変更してエラーを無音にする必要がありました。

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)

4.)セグエ先のViewControllerまたはSceneで、セグエをトリガーする場所にPostメソッドを追加します。

NotificationCenter.default.post(name: "segue" as NSNotification.Name, object: nil)

更新 -前回これを使用したときは.post、次のコードの呼び出しを変更してエラーを無音にする必要がありました。

NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "segue"), object: nil) as Notification)

スウィフト3:NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)
マイケルサモイロフ2016

3

あなたがしたいことはユニットテストにとって本当に重要です。基本的には、ビューコントローラーで小さなローカル関数を作成する必要があります。関数に任意の名前を付け、単にを含めますperformSegueWithIndentifier

func localFunc() {
    println("we asked you to do it")
    performSegueWithIdentifier("doIt", sender: self)
}

次に、ユーティリティクラスFBManagerを変更して、関数の引数をとるイニシャライザと、セグエを実行するViewControllerの関数を保持する変数を含めます。

public class UtilClass {

    var yourFunction : () -> ()

    init (someFunction: () -> ()) {
        self.yourFunction = someFunction
        println("initialized UtilClass")
    }

    public convenience init() {
        func dummyLog () -> () {
            println("no action passed")
        }
        self.init(dummyLog)
    }

    public func doThatThing() -> () {
        // the facebook login function
        println("now execute passed function")
        self.yourFunction()
        println("did that thing")
    }
}

(便利なinitを使用すると、セグエを実行せずにこれを単体テストで使用できます。)

最後に、// todo:segue to the next view ???がある場合、次の行に沿って何かを配置します。

self.yourFunction()

単体テストでは、次のように呼び出すだけです。

let f = UtilClass()
f.doThatThing()

ここで、doThatThingはfbsessionstatechangeでUtilClassあり、FBManagerです。

実際のコードでlocalFuncは、FBManagerクラスに(括弧なしで)渡すだけです。


2

これでうまくいきました。

まず、ストーリーボードのビューコントローラーにIDインスペクター内のストーリーボードIDを与えます。次に、次のコード例を使用します(クラス、ストーリーボード名、ストーリーボードIDが、使用しているものと一致することを確認してください)。

let viewController:
UIViewController = UIStoryboard(
    name: "Main", bundle: nil
).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
// .instantiatViewControllerWithIdentifier() returns AnyObject!
// this must be downcast to utilize it

self.presentViewController(viewController, animated: false, completion: nil)

詳細については、参照してくださいhttp://sketchytech.blogspot.com/2012/11/instantiate-view-controller-using.html 最高の願いを


1

performSegueWithIdentifier関数を使用してこれを行うことができます。

スクリーンショット

構文:

func performSegueWithIdentifier(identifier: String, sender: AnyObject?)

例:

 performSegueWithIdentifier("homeScreenVC", sender: nil)

1

別のオプションは、モーダルセグエを使用することです

ステップ1:ストーリーボードに移動し、View ControllerにストーリーボードIDを割り当てます。ストーリーボードIDを変更する場所は、右側のIDインスペクターで確認できます。ストーリーボードIDを呼び出しましょうModalViewController

ステップ2: 'sender'ビューコントローラーを開き(ViewControllerこれを呼び出しましょう)、このコードを追加します

public class ViewController {
  override func viewDidLoad() {
    showModalView()
  }

  func showModalView() {
    if let mvc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as? ModalViewController {
      self.present(mvc, animated: true, completion: nil)
    }
  }
}

開きたいView Controllerも呼ばれていることに注意してください ModalViewController

ステップ3: ModalViewControllerを閉じるには、これを追加します

public class ModalViewController {
   @IBAction func closeThisViewController(_ sender: Any?) {
      self.presentingViewController?.dismiss(animated: true, completion: nil)
   }
}

0

これは私のために働きました:

//Button method example
 @IBAction func LogOutPressed(_ sender: UIBarButtonItem) {

        do {
            try Auth.auth().signOut()
            navigationController?.popToRootViewController(animated: true)

        } catch let signOutError as NSError {
          print ("Error signing out: %@", signOutError)
        }


    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.