xcode 有没有可能在故事板中定义一个“通用的”展开阶段?

7ajki6be  于 2023-02-05  发布在  其他
关注(0)|答案(2)|浏览(117)

我对IOS开发比较陌生,来自Android背景,我正在寻找一种方法,一旦用户注销,就可以返回到我原来的视图控制器。
这篇文章How can I go back to the initial view controller in Swift?建议我应该使用一个放松的segue。
然而,我的应用程序中的用户会话可能在任何时候从任何视图控制器过期,这要求我创建一个从每个视图控制器到根视图控制器的回退segue,此外,这会导致代码重复,因为每个视图控制器都需要标识自己的特定segue ID。
最初,我希望对UIViewController进行子类化,并创建一个CustomViewController,然后所有其他ProfileViewController, LoginViewController都将在此基础上进行子类化。
CustomViewController会提供func logOut()这样的辅助方法。有没有办法做到这一点,也许是通过一些通用的展开segue?一个在未来自动“继承”的方法?

vwkv1x7d

vwkv1x7d1#

你不能有通用的展开segue。你不能继承ViewController的故事板属性,包括与ViewController关联的segue。但是你不需要一个通用的segue来解决你的问题。
您可以有一个BaseViewController,所有其他View Controller都将从BaseViewController扩展。您可以添加逻辑来验证用户是否仍在您的BaseViewController中登录(我无法为此编写代码,因为我没有看到您的代码库)。
如果用户不再登录,则只需调用

class BaseViewController : UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //implement your logic to monitor if user is still logged in if user not logged in simply call
        self.logOut()
    }

    func logOut() {
       //each child view controller will override and handle log out condition specifically for that ViewController
    }
}

最后,要加载初始ViewController,您可以简单地说pop all viewController on the top。假设您的initialViewController是应用的rootViewController,您可以简单地将BaseViewController中的逻辑修改为

override func viewDidLoad() {
        super.viewDidLoad()
        //implement your logic to monitor if user is still logged in if user not logged in simply call
        self.logOut()
        UIApplication.shared.keyWindow?.rootViewController?.navigationController?.popToRootViewController(animated: true)
    }

方法问题:

根据您的问题描述,我相信您的初始视图控制器保存在ViewController堆栈中,您只需在注销时展开到初始ViewController。
尽管这种方法行之有效,但它有三个问题

  1. Initial ViewController不必要地保留在内存中,因为它在用户注销之前不会重新出现,所以实际上您可以在用户登录后将其删除,并在用户注销后将其恢复。
    1.如果用户登录并退出应用程序并重新启动应用程序,应用程序将加载初始视图控制器,但如果用户已经登录,为什么还要再次向他显示初始视图控制器?
    1.因为您在初始视图控制器上推送其他VC,这也意味着用户可以简单地点击返回按钮并返回到初始视图控制器,这没有意义,因为用户点击返回按钮与用户登录状态有什么关系?不是吗?

那更好的办法是什么

在应用启动时更改应用的根视图控制器。
打开AppDelegate并

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
   //check if user is logged in

   guard let window = UIApplication.shared.keyWindow else {
        return
   }

   if (userIsLoggedIn) {
      //load view controller that you wanna show after login lets say Home
      let homeVC = //instantiate view controller from story board
      UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
            window.rootViewController = homeVC
        }, completion: { completed in
            // maybe do something here
        })
   }
   else {
       //load initial controller 
      let initialVC = //instantiate view controller from story board
      UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
            window.rootViewController = initialVC
        }, completion: { completed in
            // maybe do something here
        })
   }
}

最后,如果用户没有登录,你结束加载初始VC,一旦用户登录你的初始VC,你可以使用我上面写的代码来改变根VC

let initialVC = //instantiate view controller from story board
      UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
            window.rootViewController = initialVC
        }, completion: { completed in
            // maybe do something here
        })
vojdkbi0

vojdkbi02#

如果你想返回登录视图控制器,你可以设置从下一个视图到该视图的单次回退(退出)。然后使用通知中心从应用中的任何位置发布通知。“登录后”视图会观察通知并执行回退。

相关问题