iOS应用后台长时间停留后返回根ViewController问题求助
解决iOS应用后台返回后回到Root ViewController的问题
哥们,这个问题我太熟了——很多开发者第一次遇到后台回到root VC的情况,核心都是没搞明白iOS的状态保存与恢复机制。你说的WhatsApp能保持在之前的页面,本质就是它把用户的页面状态完整保存了,哪怕系统因为内存紧张把App进程杀掉,重启后也能恢复到用户离开时的界面。下面给你一步步说怎么实现:
一、先开启全局的状态恢复开关
iOS默认是不开启状态恢复的,得先在入口处打开这个功能:
针对iOS13+(用SceneDelegate的情况)
在scene(_:willConnectTo:options:)方法里加上这两句:
scene.delegate = self scene.shouldRestoreSecureApplicationState = true
同时你的SceneDelegate要实现UIWindowSceneDelegate的状态恢复相关方法:
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? { // 这里可以返回自定义的UserActivity,用来标记恢复状态 return scene.userActivity } func restoreUserActivityState(_ activity: NSUserActivity) { // 恢复时的逻辑,一般系统会自动处理导航栈,除非有自定义需求 }
针对iOS12及以下(用AppDelegate的情况)
在application(_:didFinishLaunchingWithOptions:)里设置:
application.shouldSaveApplicationState = true application.shouldRestoreApplicationState = true
二、给每个视图控制器和导航控制器设置恢复标识符
这是关键!系统需要通过唯一的标识符来识别要恢复的页面,所以:
- 每个你想保存状态的VC(比如ViewControllerA、B、C),都要设置
restorationIdentifier,可以在代码里或者Storyboard中配置:class ViewControllerC: UIViewController { override func viewDidLoad() { super.viewDidLoad() restorationIdentifier = "ViewControllerC" // 必须唯一 restorationClass = ViewControllerC.self // 可选,如果你有自定义恢复逻辑的话 } } - 你的UINavigationController(或者TabBarController,如果用了的话)也必须设置恢复标识符,比如:
要是用Storyboard,直接在属性面板里勾选“Restoration ID”并填写对应名称就行。let mainNav = UINavigationController(rootViewController: ViewControllerA()) mainNav.restorationIdentifier = "MainNavigationController"
三、保存自定义状态(可选但推荐)
如果你的VC里有需要恢复的用户数据(比如文本框输入内容、表格滚动位置、开关状态),可以重写这两个方法:
override func encodeRestorableState(with coder: NSCoder) { // 保存自定义数据,比如文本框内容 coder.encode(myTextField.text, forKey: "MyTextFieldContent") super.encodeRestorableState(with: coder) // 一定要调用父类方法,否则系统默认的状态存不了 } override func decodeRestorableState(with coder: NSCoder) { super.decodeRestorableState(with: coder) // 先恢复系统默认状态 // 恢复自定义数据 myTextField.text = coder.decodeObject(forKey: "MyTextFieldContent") as? String }
四、测试验证
你可以用Xcode的“Simulate Memory Warning”功能(在Debug菜单里),或者直接在模拟器/真机上把App划掉杀掉进程,然后重新打开,看看是不是能回到ViewControllerC。
另外要注意:如果你的App用了一些第三方导航库,可能需要额外适配状态恢复;还有,恢复逻辑里别做耗时操作,不然会影响启动速度。
内容的提问来源于stack exchange,提问作者Anirudha Mahale
相关产品推荐
相关产品推荐

