I can get the first row of visible cells in a table view by:
let topRow = tableView?.indexPathsForVisibleRows![0]
I want to save this NSIndexPath
so that when the app starts next time, the table view can scroll to the same position just like where it was left.
I think I should save topRow.row and topRow.section. Is there anything else? Or is there any better way?
For this kind of thing using NSUserDefaults
is not a bad idea. I suggest reading this post for detailed information.
TLDR;
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(indexPath.row, forKey: "LastVisibleRowKey")
defaults.setInteger(indexPath.section, forKey: "LastVisibleSectionKey")
In order to retrieve the saved items you do:
let row = defaults.integerForKey("LastVisibleRowKey")
I hope that helps.
NSIndexPath
implements the NSSecureCoding
protocol. This means that you can use NSKeyedArchiver
and NSKeyedUnarchiver
to convert the index path to data that can be stored in a plist or user defaults.
The pattern is described here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DrawColor/Tasks/StoringNSColorInDefaults.html
Example:
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)
}
You can use NSKeyedArchiver
archiveRootObject
to write your index data to a plist file at the library preferences directory and unarchive it using NSKeyedUnarchiver
unarchiveObjectWithFile
. Just create a property called lastSelectedIndex with a getter and a setter to save and load it automatically:
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)
}
}
In your method didSelectRowAtIndexPath set your lastSelectedIndex:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
lastSelectedIndex = indexPath
// your code
}
And load it as follow:
override func viewDidLoad() {
super.viewDidLoad()
guard let lastSelectedIndex = lastSelectedIndex else { return }
tableView.selectRowAtIndexPath(lastSelectedIndex, animated: false, scrollPosition: .None)
}
A better way would be to use State Restoration , instead of trying to persist UIKit state on your own.
The App Programming Guide for iOS documentation covers how to enable state preservation and restoration for your app.
From the user's perspective, quitting an app should just seem like a temporary interruption. When the user returns to an app, that app should always return the user to the last point of use, so that the user can continue with whatever task was in progress. This behavior provides a better experience for the user and with the state restoration support built in to UIKit is relatively easy to achieve.
The state preservation system in UIKit provides a simple but flexible infrastructure for preserving and restoring the state of your app's view controllers and views.
As you can see, it can preserve far more than just a tableView's content offset, for you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.