我可以通过以下方式获取表格视图中的第一行可见单元格:
let topRow = tableView?.indexPathsForVisibleRows![0]
我想保存此NSIndexPath
,以便下次启动应用时,表格视图可以滚动到相同的位置,就像它离开的位置一样。
我想我应该保存topRow.row和topRow.section。还有别的事吗?还是有更好的方法吗?
答案 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
协议。这意味着您可以使用NSKeyedArchiver
和NSKeyedUnarchiver
将索引路径转换为可以存储在plist或用户默认值中的数据。
示例:
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。
从用户的角度来看,退出应用程序应该只是暂时的中断。当用户返回应用程序时,该应用程序应始终将用户返回到最后一个使用点,以便用户可以继续执行正在进行的任何任务。这种行为为用户提供了更好的体验,并且UIKit内置的状态恢复支持相对容易实现。
UIKit中的状态保存系统提供了一个简单但灵活的基础结构,用于保留和恢复应用程序视图控制器和视图的状态。
正如您所看到的,它可以为您保留远远不仅仅是tableView的内容偏移量。