Ios VIEWDID显示延迟0.5秒
祝贺你 我对快速发展真的很陌生,所以请不要对我发疯:3 我已经为我的移动应用程序创建了登录页面(Firebase电子邮件+密码) 我已经实现了一个“自动登录”功能——因此,当用户第一次登录时,用户在关闭并打开应用程序后仍保持登录状态 问题是,每次用户打开应用程序时,Ios VIEWDID显示延迟0.5秒,ios,swift,Ios,Swift,祝贺你 我对快速发展真的很陌生,所以请不要对我发疯:3 我已经为我的移动应用程序创建了登录页面(Firebase电子邮件+密码) 我已经实现了一个“自动登录”功能——因此,当用户第一次登录时,用户在关闭并打开应用程序后仍保持登录状态 问题是,每次用户打开应用程序时,viewDidLoad和viewDidAppear->之间都会有一点延迟,导致每次应用程序打开时,您都可以看到登录屏幕约0.4秒,直到它自动将用户签入 用户登录后,将用户分割(无动画)到myUITabBarController 我已经
viewDidLoad
和viewDidAppear
->之间都会有一点延迟,导致每次应用程序打开时,您都可以看到登录屏幕约0.4秒,直到它自动将用户签入
用户登录后,将用户分割(无动画)到myUITabBarController
我已经为我的LoginViewController
提供了代码
LoginViewController是应用程序加载到的第一个控制器
致意
class LoginViewController: UIViewController {
@IBOutlet weak var loginEmail: UITextField!
@IBOutlet weak var loginPassword: UITextField!
@IBOutlet weak var loginBorder: UIButton!
let userDefault = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
if userDefault.bool(forKey: "usersignedin") {
performSegue(withIdentifier: "login", sender: self)
}
//Border color button//
loginBorder.layer.borderColor = UIColor.white.cgColor
//Border color button//
//Hide Keyboard Use
self.hideKeyboardWhenTappedAround()
//Hide Keyboard Use
//start padding function for login
addPaddingAndBorder(to: loginEmail)
addPaddingAndBorder(to: loginPassword)
//start padding function for login
}
@IBAction func loginButton(_ sender: UIButton) {
Auth.auth().signIn(withEmail: loginEmail.text!, password: loginPassword.text!) { (user, error) in
if user != nil {
self.userDefault.set(true, forKey: "usersignedin")
self.userDefault.synchronize()
self.performSegue(withIdentifier: "login", sender: self)
} else {
let alert = UIAlertController(title: "Invalid Email or Password", message: nil, preferredStyle: .alert)
let okButton = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
}
}
}
}
如果
usersignedin=true
,则将调用移动到performsgue(标识符为:sender:)
到viewwillbeen(:)
而不是viewdidbeen(:)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if userDefault.bool(forKey: "usersignedin") {
performSegue(withIdentifier: "login", sender: self)
}
}
另外,主线程
上未接收到signIn
方法的响应。由于您没有在主线程上更新UI
,这就是导致延迟的原因
将signIn
方法的closure
中的UI
部分嵌入DispatchQueue.main.async
Auth.auth().signIn(withEmail: loginEmail.text!, password: loginPassword.text!) { (user, error) in
if user != nil {
self.userDefault.set(true, forKey: "usersignedin")
self.userDefault.synchronize()
DispatchQueue.main.async { //here..........
self.performSegue(withIdentifier: "login", sender: self)
}
}
else {
let alert = UIAlertController(title: "Invalid Email or Password", message: nil, preferredStyle: .alert)
let okButton = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okButton)
DispatchQueue.main.async { //here..........
self.present(alert, animated: true, completion: nil)
}
}
}
这是正确的系统行为ViewDidLoad
总是比ViewDidDisplay
更早被调用。如果要基于userDefault.bool(forKey:“usersignedin”)
更改基本视图控制器,请将该逻辑添加到设置主视图控制器的位置,并在已登录时交换它们。更改视图控制器的顺序。始终首先加载UITabBarController
(作为初始控制器)。然后,在您的UITabBarController
viewDidLoad
中,检查用户是否登录。如果没有,则显示登录屏幕。这样,始终首先加载UITabBarController
,然后根据自动登录条件显示登录屏幕。因此,当用户自动输入时,您的延迟问题将不会出现
我在我所有的应用程序中都使用了这个概念,它工作得很好。viewdideappear(:)
在视图出现后立即出现。我建议将您的代码从viewdidispect(:)
移动到viewwillispect(:)
您还可以在viewdiload()
中添加登录代码,因为此方法甚至在viewwillbeen(:)
出现之前就被调用了
在您的情况下,您的代码将是:
override func viewDidLoad(){
super.viewDidLoad()
if userDefault.bool(forKey:“usersignedin”){
性能检查(标识符为“登录”,发件人为自我)
}
}
更多信息:
加载视图时,会按特定顺序调用不同的方法:
viewDidLoad()
(仅在创建对象时使用一次。)
视图将出现(:)
[视图显示在屏幕上]
viewdide出现(:)
将另一个视图控制器推到该视图控制器上时,该视图控制器不会从视图控制器堆栈中删除。重要的是,当您回到这个视图控制器时,这次不会调用viewDidLoad()
。因此,只有这些方法会按以下顺序再次调用:
视图将出现(:)
[视图显示在屏幕上]
viewdide出现(:)
在我当前的项目中,我们正在做类似的事情,但是我们决定在AppDelegate
中首先显示哪个控制器
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
var storyboard: UIStoryboard!
if isLoggedIn {
storyboard = UIStoryboard(name: "main", bundle: nil)
}
else {
storyboard = UIStoryboard(name: "login", bundle: nil)
}
let viewController = storyboard.instantiateInitialViewController()!
viewController.loadViewIfNeeded()
window.rootViewController = viewController
}
这样做的好处是,当应用程序加载时,它会立即将您带到正确的ViewController
,而不会首先短暂显示错误的控制器。最好的方法是根据登录状态在AppDelegate中决定加载哪个控制器
let navigationController = UINavigationController()
navigationController.navigationBar.barStyle = .black
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if UserDefaults.standard.object(forKey: "Token") != nil{
let initialViewController = storyboard.instantiateViewController(withIdentifier: "HomeViewController")
navigationController.viewControllers = [initialViewController]
} else{
let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
navigationController.viewControllers = [initialViewController]
}
navigationController.navigationBar.barTintColor = UIColor.black
navigationController.navigationBar.tintColor = UIColor.white
navigationController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
OP也应该这样做,但不是他问的。@Maximilian我看OP没有按照我的建议做。你好!谢谢你的回答!我的主视图控制器是LoginViewController tho。您的意思是我必须将userDefault.bool(forKey:“usersignedin”)移动到UITabBarController中吗?您可以将其移动到AppDelegate中,在窗口中设置rootViewController
,然后决定应首先显示哪个控制器。我看到另一个答案提到始终显示选项卡栏,然后在需要时在顶部显示登录,但我不喜欢这种方法,因为这意味着其中一个选项卡栏控制器必须知道如何显示登录。