我在我的应用程序中设置了touchID并正常工作.
但是,我想更改“输入密码”的功能.
创建我的身份验证时,我遵循以下教程:http://www.appcoda.com/touch-id-api-ios8/
但是,他们使用alertView作为“输入密码”选项.
我想解雇touchID alertview并让我的passwordTextField成为第一个响应者.
当然我试过了:
self.passwordTextField.becomeFirstResponder()
但这会导致错误:
2015-04-09 10:48:42.309 Formula Stocks[3933:964941] *** Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *,UIView<NSTextContainerView> *,NSTextContainer *,NSUInteger)(),/SourceCache/UIFoundation/UIFoundation-371.13/UIFoundation/TextSystem/NSLayoutManager_Private.m:1547 2015-04-09 10:48:42.312 Formula Stocks[3933:964941] <nsxpcconnection: 0x1701061e0> connection to service named com.apple.CoreAuthentication.daemon: Warning: Exception caught during decoding of received reply to message 'evaluatePolicy:options:reply:',dropping incoming message and calling failure block. Exception: Only run on the main thread!
这是我的身份验证功能:
func requestFingerprintAuthentication() { // Get the local authentication context. let context = LAContext() // Declare a NSError variable. var error: NSError? // Set the reason string that will appear on the authentication alert. var reasonString = "Sign In." // Check if the device can evaluate the policy. if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics,error: &error) { [context .evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics,localizedReason: reasonString,reply: { (success: Bool,evalPolicyError: NSError?) -> Void in if success { NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in println("successfull signin with touchID") self.emailTextField.text = emailID as! String self.passwordTextField.text = passwordID as! String self.signIn(self.signInButton) }) } else{ // If authentication Failed then show a message to the console with a short description. // In case that the error is a user fallback,then show the password alert view. println(evalPolicyError?.localizedDescription) switch evalPolicyError!.code { case LAError.SystemCancel.rawValue: println("Authentication was cancelled by the system") case LAError.UserCancel.rawValue: println("Authentication was cancelled by the user") case LAError.UserFallback.rawValue: println("User selected to enter custom password") self.passwordTextField.becomeFirstResponder() default: println("Authentication Failed") self.passwordTextField.becomeFirstResponder() } } })] } else{ // If the security policy cannot be evaluated then show a short message depending on the error. switch error!.code{ case LAError.TouchIDNotEnrolled.rawValue: println("TouchID is not enrolled") case LAError.PasscodeNotSet.rawValue: println("A passcode has not been set") default: // The LAError.TouchIDNotAvailable case. println("TouchID not available") } // Optionally the error description can be displayed on the console. println(error?.localizedDescription) // Show the custom alert view to allow users to enter the password. //self.showPassworDalert() self.passwordTextField.becomeFirstResponder() } }
它会打印出来
Optional("Fallback authentication mechanism selected.") User selected to enter custom password
所以我知道它正在调用正确的.case
任何帮助它选择我的UITextField将不胜感激!
解决方法
您需要在主线程上放置becomeFirstResponder. iOS要求所有UI操作都在主线程上.在使用闭包时(Objective-C中的块),您经常会在主线程上意外地关闭UI.你得到的常见错误是UI“冻结”了几秒钟.这是你需要时不在主线程上的经典案例.
您的情况略有不同,但控制台中的日志给出了答案:“例外:仅在主线程上运行!”