1. ホーム
  2. ios

[解決済み] Swift の performSegueWithIdentifier が動作しない。

2022-02-11 07:09:05

質問

ユーザーがアカウントへのログインに成功した後、ビューコントローラーを切り替えようとしていますが、正しく動作しません。ログインボタンがクリックされると、情報が正しいかどうかにかかわらず、そのビューコントローラに移動してしまうので、セグエを直接使用することができません。知っている限りのことをすべて試しましたが、成功しませんでした。これは私が試しているコードです。

   @IBAction func loginTapped(sender: AnyObject) {

    let username = usernameField.text
    let password = passwordField.text

    if username.isEmpty || password.isEmpty {
        var emptyFieldsError:UIAlertView = UIAlertView(title: "Please try again", message: "Please fill in all the fields we can get you logged in to your account.", delegate: self, cancelButtonTitle: "Try again")
        emptyFieldsError.show()
    }

    PFUser.logInWithUsernameInBackground(username, password:password) {
        (user: PFUser?, error: NSError?) -> Void in
        if user != nil {
            self.performSegueWithIdentifier("Klikur", sender: self)
        } else {
            if let errorString = error!.userInfo?["error"] as? String {
                self.errorMessage = errorString
            }

            self.alertView("Please try again", message: "The username password combiation you have given us does not match our records, please try again.", buttonName: "Try again")
        }
    }

}

ストーリーボードIDを"Test"に設定していますが、正しい情報が入力されてもビューコントローラーが切り替わりません。どなたか、この問題を解決する手助けをしていただけませんか?

解決方法は?

[コードがクラッシュしているのではなく、セグメンテーションに失敗しているだけだと仮定して]。

少なくとも一つの問題は

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

であるべきです。

dispatch_async(dispatch_get_main_queue()) {
    [unowned self] in
    self.performSegueWithIdentifier("Test", sender: self)
}

すべてのUI操作は、メインスレッドのキューで実行されなければならないことを忘れないでください。確認することで、間違ったスレッドにいることを自分で証明することができます。

NSThread.isMainThread() // is going to be false in the PF completion handler

付録

もし可能性があるなら self が nil になる可能性がある場合、例えば、不要になったので棄却されるとか、 他の方法で割り当てが解除されるとか、そのような場合は、self を [weak self] ではなく unowned で、安全なアンラップを使用します。 if let s = self { s.doStuff() } またはオプションのチェーニングを使用します。 self?.doStuff(...)

付録2

これは人気のある答えのようなので、この新しい選択肢をここで紹介しておくことが重要です。

NSOperationQueue.mainQueue().addOperationWithBlock {
     [weak self] in
     self?.performSegueWithIdentifier("Test", sender: self)
}

https://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift :

NSOperation vs. Grand Central Dispatch (GCD)

GCD [dispatch_* calls] は、同時に実行される仕事の単位を表現する軽量な方法です。

NSOperationはGCDに比べ若干のオーバーヘッドを追加しますが、様々な操作の間に依存性を持たせ、再利用、キャンセル、中断を行うことができます。

補遺3

Appleはここでシングルスレッド・ルールを隠蔽しています。

<ブロッククオート

注意

ほとんどの場合、UIKitのクラスはアプリのメインスレッドからのみ使用するようにしてください。 これは特に、UIResponderから派生したクラスや、UIKitに関連するクラスについて当てはまります。 アプリのユーザーインターフェイスを何らかの形で操作することになります。

SWIFT 4

DispatchQueue.main.async(){
   self.performSegue(withIdentifier: "Test", sender: self)
}

参考

https://developer.apple.com/documentation/uikit