我是Swift的新手,但我正在创建一个应用程序,需要在一定时间后输入Touch-ID或PIN。我正在检查来自AppDelegate.swift的计时器,看看它是否已经过期,如果它已经过期,我将调用我的"BaseTableViewController“,它包含我的函数authenticateUser。我再一次从我的AppDelegate.swift文件中调用它,方法是创建一个BaseTableViewController var baseTableVC = BaseTableViewController()的实例,并在计时器过期时调用self.baseTableVC.authenticateUser()。
无论如何,我得到了:警告:Attempt to present <UIAlertController: 0x7fed5ae1dcf0> on <admin.BaseViewController: 0x7fed5ad279d0> whose view is not in the window hierarchy!
提前感谢您的帮助!
func showPasswordAlert(){
let alertController = UIAlertController(title: "Touch ID Password", message: "Please enter your password", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Cancel) {(action) -> Void in
if let textField = alertController.textFields?.first as UITextField?{
if textField.text == "hello" {
print("Authentication successfull!")
}
else{
self.showPasswordAlert()
}
}
}
alertController.addAction(defaultAction)
alertController.addTextFieldWithConfigurationHandler{(textField) -> Void in
textField.placeholder = "Password"
textField.secureTextEntry = true
}
presentViewController(alertController, animated: true, completion: nil)
}
func authenticateUser(){
let context = LAContext()
var error: NSError?
let reasonString = "Authentication is required for Admin!"
context.localizedFallbackTitle = "Enter your PIN Code"
if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error){
context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: {(success, policyError) ->Void in
if success{
print("Authentication successful!")
}
else{
switch policyError!.code{
case LAError.SystemCancel.rawValue:
print("Authentication was cancelled by the system!")
case LAError.UserCancel.rawValue:
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.showPasswordAlert()
})
print("Authentication was cancelled by the user!")
case LAError.UserFallback.rawValue:
print("User selected to enter password.")
NSOperationQueue.mainQueue().addOperationWithBlock({() -> Void in
self.showPasswordAlert()
})
default:
print("Authentication failed!")
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.showPasswordAlert()
})
}
}
})
}
else{
print(error?.localizedDescription)
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.showPasswordAlert()
})
}
var baseTableVC = BaseTableViewController()
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
let logInStatus = NSUserDefaults.standardUserDefaults()
let currentTime = NSDate().timeIntervalSince1970
let roundCurrentTime = (round(currentTime))
// Pin expire limit
let pinExpLimit: Double = 30
// Set the exact time of expire for pin
let pinExpDate = (currentTime + pinExpLimit)
let newPinExpDate = (round(pinExpDate))
if (logInStatus.doubleForKey("expPinTime") <= roundCurrentTime) {
self.baseTableVC.authenticateUser()
print("AppDelegate Pin Exp Time")
print(logInStatus.doubleForKey("expPinTime"))
//print(newPinExpDate)
print("AppDelegate Current Time")
print(roundCurrentTime)
logInStatus.setDouble(newPinExpDate, forKey: "expPinTime")
NSUserDefaults.standardUserDefaults().synchronize()
}
}发布于 2016-03-02 06:19:31
我怀疑您只是创建了BaseTableViewController的一个实例,但是在呈现UIAlertController的实例之前,您没有将它的视图添加到视图层次结构中。
如果self.baseTableVC是应用程序的根视图控制器,那么像这样的调用
baseTableVC.presentViewController(instanceOfUIAlertController, animated: true, completion: yourCompletionBlock)应该从AppDelegate内部工作。如果self.baseTableVC不是根视图控制器,请确保在应用的根VC上调用前面的命令
window.rootViewController.presentViewController(instanceOfUIAlertController, animated: true, completion: yourCompletionBlock)或者确保在视图层次结构中嵌入self.baseTableVC的视图,然后调用
baseTableVC.presentViewController(instanceOfUIAlertController, animated: true, completion: yourCompletionBlock)顺便说一句,如果你的提醒必须在应用程序中的任何地方显示,那么你的方法是可以的。相反,如果您的警报必须仅从特定屏幕显示,我将从应用程序委托中删除计时器逻辑,并将其移动到呈现视图控制器中。这将使您的应用程序委托远离不必要的代码,并将控制逻辑限制在正确的位置:呈现视图控制器
发布于 2016-03-02 08:55:34
你不能仅仅通过调用默认的构造函数来创建视图控制器的实例,使用故事板。如果我错了,请纠正我
https://stackoverflow.com/questions/35734359
复制相似问题