ユーザーがアカウントに正常にログインした後、View Controllerを切り替えようとしていますが、正しく機能していません。ログインボタンをクリックすると、情報が正しいかどうかに関係なく、そのView Controllerに移動するため、セグエを直接使用できません。知っていることはすべて試したが成功しなかった。これは私が試しているコードです。
@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を「テスト」に設定していますが、正しい情報が入力されたときにView Controllerが切り替わりません。誰かが私の問題を解決するのを手伝ってくれますか?
[コードがクラッシュせず、単にセグエに失敗すると仮定する]
少なくとも1つの問題は次のとおりです。
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になってしまう可能性がある場合は、unowned
ではなく[weak self]
として自分自身を弱くキャプチャし、安全なアンラップ: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対Grand Central Dispatch(GCD)
GCD [dispatch_ * calls]は、同時に実行される作業単位を表す軽量な方法です。
NSOperationはGCDと比較して少し余分なオーバーヘッドを追加しますが、さまざまな操作に依存関係を追加し、それらを再利用、キャンセル、または一時停止できます。
補遺3
Appleはここでシングルスレッドルールを隠しています。
注意
ほとんどの場合、アプリのメインスレッドからのみUIKitクラスを使用します。これは、UIResponderから派生したクラス、またはアプリのユーザーインターフェースを何らかの方法で操作するクラスに特に当てはまります。
Swift 4
DispatchQueue.main.async(){
self.performSegue(withIdentifier: "Test", sender: self)
}
参照:
ログインの問題にも同じ問題があります。おそらく同じチュートリアルを行います。セグエ識別子に名前を付けたら、次のものを置き換える必要があります。
performSegueWithIdentifier("Klikur", sender: self)
で:
dispatch_async(dispatch_get_main_queue()){
self.performSegueWithIdentifier("Klikur", sender: self)
}
シークのタイプは、ストーリーボードセグエで「show(e.g. Push)」として設定する必要があります。それがうまくいくことを願っています。
次のものを入れていることを確認してください:self.performSegue(withIdentifier: ..., ...)
viewDidAppear以降。 viewWillAppearまたはviewDidLoadでは機能しません。
performSegueWithIdentifier(_:sender:)
に渡すセグエ識別子はexactlyストーリーボードでセグエに指定したIDと一致する必要があります。ログインビューコントローラーと成功ビューコントローラーの間にセグエがあると仮定します。そうでない場合は、Ctrlキーを押しながら最初のView Controllerから2番目のView Controllerにドラッグし、ストーリーボードでセグエのアイコンを選択し、そのIDをKlikur
に設定します。 Do n'tボタンクリックでナビゲーションを実行します。これは、セグエを持つ主な目的を無効にするためです。これはvisualアプリケーションの表示ストーリーボードの流れ。
編集:ログインビューコントローラーのコードは次のとおりです。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var usernameField: UITextField!
@IBOutlet weak var passwordField: UITextField!
@IBAction func attemptLogin(sender: AnyObject) {
if !usernameField!.text!.isEmpty && !passwordField!.text!.isEmpty {
performSegueWithIdentifier("Klikur", sender: self)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if "Klikur" == segue.identifier {
// Nothing really to do here, since it won't be fired unless
// shouldPerformSegueWithIdentifier() says it's ok. In a real app,
// this is where you'd pass data to the success view controller.
}
}
}
Swift 3.x
DispatchQueue.main.async(){
self.performSegue(withIdentifier: "Klikur", sender: self)
}
DispatchQueue.main.async() {
self.performSegue(withIdentifier: "GoToHomeFromSplash", sender: self)`
}
表示されているView Controllerで実行セグエを実行していることを確認してください。
これはEdgeの場合ですが、現在表示されていないUIPageViewControllerに属するView Controllerで実行しようとすると、実行セグエが失敗しました。また、現在表示されているView Controllerを含む、UIPageViewControllerに属するすべてのView Controllerでセグエを実行しようとしても失敗しました。修正は、UIPageViewControllerで現在どのView Controllerが表示されているかを追跡し、そのView Controllerでのみセグエを実行することでした。
ログインの例。ボタン(アクション)をクリックした後、ログインに成功すると、次を使用できます。
self.performSegue(withIdentifier: "loginSucess", sender: nil)
ただし、アプリを起動し、キーチェーンから資格情報を取得した場合は、これを一部として使用する必要があります。
DispatchQueue.main.async(){
self.performSegue(withIdentifier: "sessionSuccess", sender: nil)
}