更改 ViewController 并重新启动应用程序

Posted

技术标签:

【中文标题】更改 ViewController 并重新启动应用程序【英文标题】:Change the ViewController and restart app 【发布时间】:2020-06-07 21:12:08 【问题描述】:

我正在制作两个 ViewController,如何将 rootViewController 从 ViewController() 更改为 MainView()?这是我在 SceneDelegate 中的代码

guard let windowScene = (scene as? UIWindowScene) else  return 
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
window?.backgroundColor = UIColor.black
if isNewUser == true 
     window?.rootViewController = ViewController()
 else 
     window?.rootViewController = MainView()

当我在运行应用程序时同时测试 isNewUser = true 和 isNewUser = false 时,这工作正常。

在我的视图控制器中

class ViewController: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        //Show the welcome screen, blah.
        //Accept the location, blah.
        //After accepted everything, change isNewUser to false in UserDefault.Standard
        print("App is restart")
    


class MainView: UITabBarController, UITabBarControllerDelegate 
    override func viewDidLoad() 
        super.viewDidLoad()
        print("Welcome to AiOO!")
    


两者都可以正常工作,但是例如,当我完成接受协议或接受的位置时,第一次运行应用程序时会出现类似的情况...它将在 UserDefault.standard 中将 isNewUser 设置为 false。所以只有一件事我卡住了,我怎样才能重新启动应用程序或将 rootViewController 切换到 MainView()??

更新: RestartApp,当我单击“完成”按钮时没有运气,没有 UITabBarControl 并且在我杀死应用程序并再次打开之前不会调用 MainView,它可以工作:( 下面是我的完整代码:

在场景代理中:

var versioncheck = "1.0.0.0"

class SceneDelegate: UIResponder, UIWindowSceneDelegate, RestartApp 

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
        sceneRestore()
        guard let windowScene = (scene as? UIWindowScene) else  return 
        window = UIWindow(windowScene: windowScene)
        window?.makeKeyAndVisible()
        window?.backgroundColor = UIColor(named: "Main Background")
        restartApp()
    
    func restartApp() 
        if !UserDefaults.standard.bool(forKey: "New User") UserDefaults.standard.set(true, forKey: "New User")
        let isNewUser = UserDefaults.standard.bool(forKey: "New User")
        print(isNewUser) // It will keep say "true" even change to false in UserDefault
        if isNewUser == true 
            window?.rootViewController = ViewController()
         else if versioncheck != "1.0.0.0" 
            window?.rootViewController = NewUpdate()
         else 
            window?.rootViewController = MainView()
        
    

视图控制器

protocol RestartApp 
    func restartApp()

class ViewController: UIViewController 
    var delegate: RestartApp?
    override func viewDidLoad() 
        super.viewDidLoad()
        welcomePage()
    

当我点击“完成”按钮时,它会调用:

@objc func welcomeChangeGoToMain () 
    UserDefaults.standard.set(false, forKey: "New User")
    print(UserDefaults.standard.bool(forKey: "New User")) //It said "false"
    welcomeTitle.removeFromSuperview()
    welcomeSubline.removeFromSuperview()
    welcomeNext.removeFromSuperview()
    welcomeRequest.removeFromSuperview()
    self.delegate?.restartApp()

【问题讨论】:

你不能重启应用,但是你可以给 rootViewController 属性分配一个新的视图控制器。 【参考方案1】:

您可以创建一个在 isNewUser 值发生变化时调用的委托协议,并在场景类中调用它的委托函数,以便根据该值呈现视图控制器。如下:

在你的 SceneDelegate 类中:

 // don't forget to assign the RestartApp Delegate here
class SceneDelegate: UIResponder, UIWindowSceneDelegate, RestartApp 

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
    guard let windowScene = (scene as? UIWindowScene) else  return 
    window = UIWindow(windowScene: windowScene)
    window?.makeKeyAndVisible()
    restartApp()

并在sceneDelegate中创建restartApp函数

    func restartApp() 
        let isNewUser = UserDefaults.standard.bool(forKey: "Key")
        if isNewUser == true 
           window?.rootViewController = ViewController()
         else 
           window?.rootViewController = ViewController2()
        

在您希望调用重启函数的最后创建协议,它的委托调用如下:

protocol RestartApp 
  func restartApp()


class ViewController2: UIViewController 

var delegate: RestartApp?

override func viewDidLoad() 
    super.viewDidLoad()
    UserDefaults.standard.set(true, forKey: "Key")
    view.backgroundColor = .yellow
    print("VC2")
    self.delegate?.restartApp() // this should be called wherever you want to restart the app ( inside an action or a function depends on your need )



总而言之,这里发生的情况是应用程序启动它调用 SceneDelegate 类中的 willConnectTo 函数,而这个调用重新启动应用程序并根据保存在 IsNewUser 中的最后一个值调用 VC,然后每次调用时在你的 VC 中self.delegate.restartApp() ,它调用 SceneDelegate 内部的重启函数并根据您的 isNewUser 值调用 VC。

【讨论】:

你能给我举个例子吗?我尝试了 MainView().viewDidLoad(),但选项卡不会显示 我拿到笔记本电脑后会分享它?抱歉延迟 检查我的答案并告诉我 检查我的编辑问题,让我知道我错过了什么 在重新启动应用程序功能时使用断点并告诉我当您按下按钮时它会被调用吗?

以上是关于更改 ViewController 并重新启动应用程序的主要内容,如果未能解决你的问题,请参考以下文章

返回第一个 ViewController 时如何阻止 AVFoundation 音频重新启动?

在 Xcode 8 和 Swift 3 中写入文本文件并在应用重新启动时保持更改 [重复]

App.config 中的更改不会在重新启动应用程序后反映出来

更改呈现的第一个 viewController(主界面)

监控 CLLocationManager 重大位置更改时应用程序不会重新启动 - iPhone

ViewController 不会在本地化应用程序中加载其 xib 文件每当我删除并重新安装时?