2017-08-29 18 views
0

我目前正在开发一个应用程序,用户必须登录应用程序的首次启动。登录被存储,以便用户在终止后每次打开应用程序时都不需要重做该过程。注销功能应该是什么样子才能“重新加载”应用程序?

我目前正试图实现一个signout按钮,删除存储的登录数据和偏好和应该“刷新”应用程序,并再次显示登录视图,就好像用户根本就不会打开应用首先是(你在Spotify等应用中看到的效果相同)。

虽然我已经设法对第一部分进行编程,但我真的很难与第二部分编程。

我第一个解决这个问题的方法是把UI和变量相关的代码转换成一个在viewDidLoad()中被调用的独立函数,并将该函数注册为一个NotificationCenter Key,以便在所有已经初始化的类上注销通过触发注销的类的NotificationCenter发布。

该方法有点工作。问题在于许多其他通知中心帖子被多次调用,导致应用程序无法正常工作,直到终止并重新启动。

我真的找不到这种行为的原因。尽管如此,我认为即使它起作用,也不是一种正确的方法来实现这一点,因为我“重新加载”(在该函数的意义上)所有类,而不仅仅是可见的类,这应该是非常低效的长期。


你会如何解决这个问题? 我不认为我是唯一一个为此而挣扎的人。 你知道“流行”应用程序如何实现这种效果吗?

PS:有没有办法“去定义”一类ViewController?如果有可能这是一种尝试的方法?

回答

2

在我看来,实施此类行为时不应依赖通知中心。如果您想用一个ViewController替换内存中的所有ViewController(例如,登录屏幕),则应该替换应用程序windowrootViewController。您可以通过简单的设置属性做到这一点:

class YourViewController { 
    static func presentOn(window: UIWindow) { 
     let vc = YourViewController.init(nibName: "YourViewController", bundle: Bundle.main) // or however you want to initialize it 
     window.rootViewController = vc 
     window.makeKeyAndVisible() 
    } 
} 

然后调用YourViewController.presentOn(UIApplication.shared.windows.first!)

或者,如果你想有动画,使用自定义赛格瑞的子类,在你与你的自定义动画覆盖perform方法(例如使用snapshot views)。

class PresentAsRootSegue: UIStoryboardSegue { 
    override func perform() { 
     let window = UIApplication.shared.windows.first! 
     destination.view.frame = window.bounds 
     let snapshot: UIView = destinationView.snapshotView(afterScreenUpdates: true) 

     UIView.animate(withDuration: 1.0, animations: { 
      //do your animations here 
     }, completion: { _ in 
      window.rootViewController = destination 
      window.windowLevel = UIWindowLevelNormal 
      source.dismiss(animated: false, completion: nil) 
     }) 
    } 
} 

然后在注销的ViewController电话PresentAsRootSegue(source: self, destination: LoginViewController()).perform()

如果变更后的老ViewControllers仍然在内存中,那么就意味着你有内存泄漏。

+0

谢谢你的回答!我应该用什么作为nibName?我在网上找不到任何名称应该是的。我使用故事板 – wyte

+0

如果您使用故事板,则使用 'let storyboard = UIStoryboard(名称:“Main”,捆绑包:Bundle。main)' then 'let viewController = storyboard.instantiateViewController(“YourViewController”)as? YourViewController' 请记住在Interface Builder中添加“Storyboard ID”名称。或者使用[SwiftGen](https://github.com/SwiftGen/SwiftGen)更容易实例化。 –

+0

现在调用onboarding:'let vc = self.storyboard?.instantiateViewController(withIdentifier:“IDLaunchViewController”)''UIApplication.shared.windows.firs t!.rootViewControlle r = vc'' UIApplication.shared.windows。第一!.makeKeyAndVisible()'它的工作!我现在还利用viewWillAppear(),viewDidAppear()和viewDidDisappear()为var相关的东西清理了我的代码,注册Notfication Center Observers并删除Notification Center Observers。 – wyte

相关问题