接手一个项目, 其中有一个登录超时的功能未实现, 在实现的过程中遇到了一些问题.记录下来, 也给其他遇到相似问题的人一些参考
项目的层级结构如下图:
实现超时退出功能的思路:
在网络请求方法中, 根据返回的 json 字符串中的 code 值判断, 如果 code 为约定的值, 则退出登录.
错误方法:
因为对层级关系理解的不够清楚, 刚开始走了很多弯路, 使用了一个很麻烦的方法: 先获取当前 currentVC , 再从当前控制器 pop 到 logInVC
//退出登录
func toLogOut() {
MBProgressHUD.showText("退出成功", toView: nil)
let currentVC = getCurrentVC()//获取当前视图控制器
let originNav = UIApplication.shared.keyWindow?.rootViewController//获取 keyWindow 的 rootViewController
if let nav = originNav as? UINavigationController {
//******错误写法****
currentVC.navigationController?.popToRootViewController(animated: true)
}
}
获取当前视图参考: 获取当前视图
private func getCurrentVC(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController {
if let presented = base?.presentedViewController {
return getCurrentVC(base: presented)
}
if let nav = base as? UINavigationController {
return getCurrentVC(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
return getCurrentVC(base: tab.selectedViewController)
}
return base!
}
方法执行但是没有跳转
原因: 根据图1 项目的层级结构, currentVC (假设 currentVC 为 图1中的 vc1)的 navigationController 为 Nav1, 而不是 pop 到 LoginVC 需要的 Nav0, 所以此时实际是从 VC1 pop 到 VC1
解决办法:
方法一: 将
currentVC.navigationController?.rootViewController.popToRootViewController(animated:true)
改为
currentVC.navigationController?.navigationController?.rootViewController.popToRootViewController(animated:true)
方法二: 更简单的可以不用获取当前视图, 所有视图统一从 tabBar 控制器 pop 到 LoginVC
func toLogOut() {
MBProgressHUD.showText("退出成功", toView: nil)
let originNav = UIApplication.shared.keyWindow?.rootViewController
if let nav = originNav as? UINavigationController {
let tab = nav.topViewController!
tab.navigationController?.popToRootViewController(animated: true)
}
}