Summary:
What's the proper way to save/restore the state of an NSSearchField
in my NSViewController
using the built-in user interface preservation mechanism of Cocoa?
Details:
I'm working on my first macOS app and I'm having a little trouble with state restoration for my user interface. So far I have it working to the point where the encodeRestorableState(with:)
and restoreState(with:)
methods are called in my NSViewController
subclass.
I have an NSSearchField
in my view controller and I want to save/restore the state of the search field including its text, any selection, the cursor position, and whether it is currently in focus or not.
If I use the following code, the text is properly saved and restored:
override func encodeRestorableState(with coder: NSCoder) {
super.encodeRestorableState(with: coder)
coder.encode(searchField.stringValue, forKey: "searchText")
}
override func restoreState(with coder: NSCoder) {
super.restoreState(with: coder)
if let searchText = coder.decodeObject(forKey: "searchText") as? String {
searchField.stringValue = searchText
}
}
Obviously I can add more code to save/restore the search field's selection and cursor position, etc.
My real question is, is there a better, proper, more automatic way to save and restore the search field's state? Or is it required that I write my own code for each attribute of the search field I wish to save?
I tried using:
searchField.encodeRestorableState(with: coder)
and:
searchField.restoreState(with: coder)
in the two above methods but that didn't result in anything appearing in the search field when my app was restarted.
I also implemented:
override class func restorableStateKeyPaths() -> [String] {
var keys = super.restorableStateKeyPaths()
keys.append("searchField.stringValue")
return keys
}
where "searchField"
is the name of the NSTextField
outlet property in my view controller. This method is called when my app is launched but the text was not restored in the search field.
This view controller is created from a storyboard. The view controller's identifier
is set. The search field's identifier
is set as well. This view controller is a child view controller of another view controller.
I've read through the User Interface Preservation section of the "The Core App Design" document but it's unclear on how a view controller's views are saved/restored and how much of this is automatic versus manual.
Supporting OSX 10.12 and 10.11. Objective-C or Swift in any answers is fine.
restorableStateKeyPaths
method and use it to specify key paths for any attributes to be preserved. Cocoa uses the key paths to locate and save the data for the corresponding attribute. Attributes must be compliant with key-value coding and Key-value observing."? – SuperjacentNSTextField
attribute. The method is called but the text field is not restored. – Endorse.stringValue
portion of the key path. It should drill down to the value itself, not the control. – Superjacent"searchField.stringValue"
. – EndorsestringValue
yourself before restoration, it seems the restoration process won't override with store value. "The above step isn’t necessary when using+restorableStateKeyPaths
because KVO handles it for us." bignerdranch.com/blog/cocoa-ui-preservation-yall – SuperjacentstringValue
. – EndorseNSTextField
doesn't implement restoration methods. IsstringValue
KVO compliant? – DetroitrestorableStateKeyPaths
). Perhaps you can subclass NSSearchField and implementrestorableStateKeyPaths
there. – Foothill