Swift App状态恢复-State Restoration(一)
原创Blog,转载请注明出处 前言: 本文主要讲诉如何用Storyboard进行状态恢复,下一篇更新如何实现代码State Restoration。 注意: 一 什么是状态相关的信息?就是那些不容易被重新创建的信息,比如一个tableview,当前选择的是哪行?比如用户的first responser是什么?比如tabController当前选择是哪个页面。 二 如何实现保存状态信息
encodeRestorableStateWithCoder:
decodeRestorableStateWithCoder:
另外,可以使用App 代理来存储版本等额外信息 application:willEncodeRestorableStateWithCoder: and application:didDecodeRestorableStateWithCoder:
三 State Restoration的流程保存状态的流程图 恢复状态的流程图 从视图控制器的生命周期来看 awakeFromNib viewDidLoad decodeRestorableStateWithCoder: viewWillAppear viewDidAppear 如果是用代码实现的 +viewControllerWithRestorationIdentifierPath:coder:
awakeFromNib
viewDidLoad
decodeRestorableStateWithCoder:
viewWillAppear
viewDidAppear
注意:比如v3->v2->v1,是层次结构,如果v2没有标识符,那么底层的v3即便有标识符也没办法恢复。一组层次结构要保存,一定要都有restorationIdentifier 四 Demo项目链接 如何测试 首先,在AppDelegate中实现两个代理函数 func application(application: UIApplication,shouldRestoreApplicationState coder: NSCoder) -> Bool {
return true
}
func application(application: UIApplication,shouldSaveApplicationState coder: NSCoder) -> Bool {
return true
}
然后,看一下我的Storyboad上的架构 对每一个Storyboard上的vc都设置restoration identifiers,如图 对Tabbar当前选择哪个VC进行保存恢复 let KTABBARSELECTINDEX = "SelectIndex"
class MainTabbarController:UITabBarController{ override func encodeRestorableStateWithCoder(coder: NSCoder) { let selectindex = self.selectedIndex; coder.encodeInteger(selectedIndex,forKey: KTABBARSELECTINDEX) //Do not forget to call super super.encodeRestorableStateWithCoder(coder) } override func decodeRestorableStateWithCoder(coder: NSCoder) { let selectindex = coder.decodeIntegerForKey(KTABBARSELECTINDEX) self.selectedIndex = selectindex //Do not forget to call super super.decodeRestorableStateWithCoder(coder) } }
对FirstViewController的TextField内容进行保存/恢复 let KSECONDVCTEXTFIELD = "secondvctextField"
class FirstViewController:UIViewController,UITextFieldDelegate{ @IBOutlet weak var textfield: UITextField! override func encodeRestorableStateWithCoder(coder: NSCoder) { coder.encodeObject(textfield.text,forKey: KSECONDVCTEXTFIELD) super.encodeRestorableStateWithCoder(coder) } override func decodeRestorableStateWithCoder(coder: NSCoder) { if let text = coder.decodeObjectForKey(KSECONDVCTEXTFIELD) as? String{ textfield.text = text } super.decodeRestorableStateWithCoder(coder) } func textFieldShouldReturn(textField: UITextField) -> Bool { textfield.resignFirstResponder() return true } }
对SecondViewController进行Textfield和ChildVC进行保存/恢复 let KFIRSTVCTEXTFIELD = "firstvctextField"
class SecondViewController:UIViewController,UITextFieldDelegate {
@IBOutlet weak var textfield: UITextField!
override func encodeRestorableStateWithCoder(coder: NSCoder) {
coder.encodeObject(textfield.text,forKey: KFIRSTVCTEXTFIELD)
//Parent vc should encode child vc,so that child vc can encode itself
let childVC = self.childViewControllers.first as! UINavigationController
coder.encodeObject(childVC,forKey: "childVC")
super.encodeRestorableStateWithCoder(coder)
}
override func decodeRestorableStateWithCoder(coder: NSCoder) {
if let text = coder.decodeObjectForKey(KFIRSTVCTEXTFIELD) as? String{
textfield.text = text
}
super.decodeRestorableStateWithCoder(coder)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textfield.resignFirstResponder()
return true
}
}
对嵌入式的TableViwController进行当前选择的行进行保存/恢复 let KTALBLESELECTEDINDEX = "selectIndex"
class EmbedTableviewController:UITableViewController{
override func encodeRestorableStateWithCoder(coder: NSCoder) {
if let selectedIndexs = self.tableView.indexPathsForSelectedRows(){
//Encode select index
var data = NSKeyedArchiver.archivedDataWithRootObject(selectedIndexs)
coder.encodeObject(data,forKey:KTALBLESELECTEDINDEX)
}
super.encodeRestorableStateWithCoder(coder)
}
override func decodeRestorableStateWithCoder(coder: NSCoder) {
var data = coder.decodeObjectForKey(KTALBLESELECTEDINDEX) as? NSData
if data != nil{
//Decode select index
if let selectedIndexs = NSKeyedUnarchiver.unarchiveObjectWithData(data!) as? NSArray{
for var i = 0;i < selectedIndexs.count;i++ {
let oneIndex = selectedIndexs[i] as! NSIndexPath
self.tableView.selectRowAtIndexPath(oneIndex,animated:false,scrollPosition: UITableViewScrollPosition.None)
}
}
}
super.decodeRestorableStateWithCoder(coder)
}
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |