一种更好的方法来恢复被破坏的iOS UIViewControllers

时间:2015-12-02 11:30:04

标签: segue state-restoration

我有一个UITableViewController,它显示了一个选项列表。点击每个选项使用segue

导航到另一个视图控制器

需要以下代码才能恢复应用的状态。但是有更干净的方式吗?我已经包含了代码来处理列表中的两个选项但是图像10个选项!

class SettingsViewController:UITableViewController {

var isRestoration = false
var aboutVC:AboutViewController?
var feedbackVC:FeedbackViewController?

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    if isRestoration {
        isRestoration = false
        restoreChildIfPresent()
    } else {
        // nullify so when child is closed, we don't reopen
        // on next restoration
        forgetChildren()
    }
}

override func restoreChildIfPresent() {
    if let aboutVC = aboutVC {
        self.navigationController?.pushViewController(aboutVC, animated:false)
    } else if let feedbackVC = feedbackVC {
        self.navigationController?.pushViewController(feedbackVC, animated:false)
    }
}

func forgetChildren() {
    aboutVC = nil
    charterVC = nil
    feedbackVC = nil
}

override func prepareForSegue(segue:UIStoryboardSegue, sender:AnyObject?) {
    aboutVC = nil
    feedbackVC = nil
    if segue.identifier == "aboutSegue" {
        aboutVC = segue.destinationViewController as? AboutViewController    
    } else if segue.identifier == "feedbackSegue" {
        feedbackVC = segue.destinationViewController as? FeedbackViewController
    }
}

    override func decodeRestorableStateWithCoder(coder:NSCoder) {
    isRestoration = true
    aboutVC = coder.decodeObjectForKey("aboutVC") as? AboutUsViewController
    feedbackVC = coder.decodeObjectForKey("feedbackVC") as? FeedbackViewController
    super.decodeRestorableStateWithCoder(coder)
}

override func encodeRestorableStateWithCoder(coder:NSCoder) {
    coder.encodeObject(aboutVC, forKey:"aboutVC")
    coder.encodeObject(feedbackVC, forKey:"feedbackVC")
    super.encodeRestorableStateWithCoder(coder)
}

我很惊讶我需要对子VC进行encodeObject(),因为它们没有嵌入(对于那些嵌入在UITabbarController中的人,需要使用encodeObject()子)。

我的主要'不喜欢'是restoreChildIfPresent(),随着更多ViewControllers的增加以及forgetChildren()

的丑陋需求而增长

1 个答案:

答案 0 :(得分:0)

我通过使用对UIViewController的单个引用来减少我的问题中的代码,使其更易于管理。但结构是一样的。可以添加进一步的Swifty-ness但我对替代方法更感兴趣,或者确认这种方法是推荐的做法。

class SettingsViewController:UITableViewController {

var isRestoration = false
var childVC:UIViewController?

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    if isRestoration {
        isRestoration = false
        restoreChildIfPresent()
    } else {
        // nullify so when child is closed, we don't reopen
        // on next restoration
        forgetChild()
    }
}

override func restoreChildIfPresent() {
    if let childVC = childVC {
        self.navigationController?.pushViewController(childVC, animated:false)
    }
}

func forgetChild() {
    childVC = nil
}

override func prepareForSegue(segue:UIStoryboardSegue, sender:AnyObject?) {
    childVC = nil
    if segue.identifier == "aboutSegue" {
        childVC = segue.destinationViewController    
    } else if segue.identifier == "feedbackSegue" {
        childVC = segue.destinationViewController
    }
}

override func decodeRestorableStateWithCoder(coder:NSCoder) {
    isRestoration = true
    childVC = coder.decodeObjectForKey("childVC")
    super.decodeRestorableStateWithCoder(coder)
}

override func encodeRestorableStateWithCoder(coder:NSCoder) {
    coder.encodeObject(childVC, forKey:"childVC")
    super.encodeRestorableStateWithCoder(coder)
}