如何在本地保存NSIndexPath?

时间:2016-01-15 04:14:09

标签: ios swift nsindexpath

我可以通过以下方式获取表格视图中的第一行可见单元格:

let topRow = tableView?.indexPathsForVisibleRows![0]

我想保存此NSIndexPath,以便下次启动应用时,表格视图可以滚动到相同的位置,就像它离开的位置一样。

我想我应该保存topRow.row和topRow.section。还有别的事吗?还是有更好的方法吗?

4 个答案:

答案 0 :(得分:3)

对于使用NSUserDefaults的这种事情并不是一个坏主意。我建议您阅读此post以获取详细信息。

TLDR;

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(indexPath.row, forKey: "LastVisibleRowKey")
defaults.setInteger(indexPath.section, forKey: "LastVisibleSectionKey")

要检索保存的项目,请执行以下操作:

let row = defaults.integerForKey("LastVisibleRowKey")

我希望有所帮助。

答案 1 :(得分:2)

NSIndexPath实现了NSSecureCoding协议。这意味着您可以使用NSKeyedArchiverNSKeyedUnarchiver将索引路径转换为可以存储在plist或用户默认值中的数据。

此处描述了模式:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DrawColor/Tasks/StoringNSColorInDefaults.html

示例:

extension NSUserDefaults {
    func indexPathForKey(key: String) -> NSIndexPath? {
        if let data = self.objectForKey(key) as? NSData {
            if let indexPath = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? NSIndexPath {
                return indexPath
            }
        }
        return nil;
    }

    func setIndexPath(indexPath: NSIndexPath, forKey key:String) {
        self.setObject(NSKeyedArchiver.archivedDataWithRootObject(indexPath), forKey: key)
    }
}

let defaults = NSUserDefaults.standardUserDefaults()

//
// Saving an index path
//
let myIndexPath = NSIndexPath(indexes:[1, 2, 3, 4], length: 4)
defaults.setIndexPath(myIndexPath, forKey:"MyIndexPath")

//
// Loading an index path
//
if let newIndexPath = defaults.indexPathForKey("MyIndexPath") {
    print("Loaded index path: \(newIndexPath)")
    assert(myIndexPath == newIndexPath)
}

答案 2 :(得分:2)

您可以使用NSKeyedArchiver archiveRootObject将索引数据写入库首选项目录中的plist文件,并使用NSKeyedUnarchiver unarchiveObjectWithFile取消归档。只需创建一个名为lastSelectedIndex的属性,使用getter和setter自动保存并加载它:

var lastSelectedIndex: NSIndexPath? {
    get {
        guard
            let filePath = NSFileManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first?.URLByAppendingPathComponent("Preferences", isDirectory: true).URLByAppendingPathComponent("myAppData.plist").path
        else { return nil }
        return NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as? NSIndexPath
    }
    set {
        guard
            let newValue = newValue,
            filePath = NSFileManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first?.URLByAppendingPathComponent("Preferences", isDirectory: true).URLByAppendingPathComponent("myAppData.plist").path
        else { return }
        NSKeyedArchiver.archiveRootObject(newValue, toFile: filePath)
    }
}

在你的方法中,didSelectRowAtIndexPath设置你的lastSelectedIndex:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    lastSelectedIndex = indexPath
    // your code
}

按以下方式加载:

override func viewDidLoad() {
    super.viewDidLoad()
    guard let lastSelectedIndex = lastSelectedIndex else { return }
    tableView.selectRowAtIndexPath(lastSelectedIndex, animated: false, scrollPosition: .None)
}

答案 3 :(得分:0)

更好的方法是使用State Restoration,而不是试图自己坚持UIKit状态。

适用于iOS的应用程序编程指南文档涵盖了适用于您应用的how to enable state preservation and restoration

  

从用户的角度来看,退出应用程序应该只是暂时的中断。当用户返回应用程序时,该应用程序应始终将用户返回到最后一个使用点,以便用户可以继续执行正在进行的任何任务。这种行为为用户提供了更好的体验,并且U​​IKit内置的状态恢复支持相对容易实现。

     

UIKit中的状态保存系统提供了一个简单但灵活的基础结构,用于保留和恢复应用程序视图控制器和视图的状态。

正如您所看到的,它可以为您保留远远不仅仅是tableView的内容偏移量。