问题描述
我试图在用户成功登录到他们的帐户后切换视图控制器,但它无法正常工作。我不能直接使用segue,因为如果单击登录按钮,它将转到该视图控制器,无论信息是否正确。我已经尝试了所有我知道但没有成功的事情。这是我正在尝试的代码。
I am trying to switch view controllers after a user successfully logs in to their account, but it is not working correctly. I cant use a segue directly because if the login button is clicked it will go to that view controller regardless if the information is correct or not. I have tried everything that I know of with no success. This is the code I am trying.
@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设置为测试,并且在输入正确信息时不切换视图控制器。有人可以帮我解决我的问题吗?
I have the storyboard ID set to "Test" and it is not switching view controller when the correct information is entered. Can somebody help me resolve my problem?
推荐答案
[假设你的代码没有崩溃,而只是没有发生错误]
[Assuming that your code is not crashing, but rather just failing to segue]
至少有一个问题是:
self.performSegueWithIdentifier("Test", sender: self)
应为:
dispatch_async(dispatch_get_main_queue()) {
[unowned self] in
self.performSegueWithIdentifier("Test", sender: self)
}
请记住,必须在主线程的队列上执行所有UI操作。您可以通过检查证明自己错误的线程:
Remember that all UI operations must be performed on the main thread's queue. You can prove to yourself you're on the wrong thread by checking:
NSThread.isMainThread() // is going to be false in the PF completion handler
ADDENDUM
如果有任何机会 self
可能会变为零,例如因为不需要而被解雇或以其他方式解除分配,你应该自我弱化为 [弱自我]
不是无主
,并使用安全解包:如果让s = self {s。 doStuff()}
或可选链接: self?.doStuff(...)
If there's any chance self
might become nil, such as getting dismissed or otherwise deallocated because it's not needed, you should capture self weakly as [weak self]
not unowned
, and use safe unwrapping: if let s = self { s.doStuff() }
or optional chaining: self?.doStuff(...)
ADDENDUM 2
这似乎是一个受欢迎的答案,所以在这里提到这个更新的替代方案很重要:
This seems to be a popular answer so it's important to mention this newer alternative here:
NSOperationQueue.mainQueue().addOperationWithBlock {
[weak self] in
self?.performSegueWithIdentifier("Test", sender: self)
}
注意,来自:
GCD [dispatch_ * calls]是轻量级的表示将同时执行的工作单元的方法。
GCD [dispatch_* calls] is a lightweight way to represent units of work that are going to be executed concurrently.
与GCD相比,NSOperation增加了一些额外的开销,但您可以在各种操作中添加依赖关系并重新使用,取消或暂停它们。
NSOperation adds a little extra overhead compared to GCD, but you can add dependency among various operations and re-use, cancel or suspend them.
ADDENDUM 3
Apple隐藏单线程规则:
Apple hides the single-threaded rule here:
大多数情况下,仅使用应用程序主要的UIKit类线。
对于从UIResponder派生的类或者
涉及以任何方式操纵应用程序的用户界面尤其如此。
For the most part, use UIKit classes only from your app’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your app’s user interface in any way.
SWIFT 4
DispatchQueue.main.async(){
self.performSegue(withIdentifier: "Test", sender: self)
}
参考:
这篇关于Swift performSegueWithIdentifier不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!