使用Cocoa的内置用户界面保存机制,在NSViewController中保存/恢复NSSearchField状态的正确方法是什么?
细节:
我正在开发我的第一个macOS应用程序,我的用户界面状态恢复有点麻烦。到目前为止,我已经开始工作到在我的NSViewController子类中调用encodeRestorableState(with :)和restoreState(with :)方法的程度。
我的视图控制器中有一个NSSearchField,我想保存/恢复搜索字段的状态,包括文本,任何选择,光标位置,以及它当前是否处于焦点。
如果我使用以下代码,则正确保存和恢复文本:
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 } }
显然我可以添加更多代码来保存/恢复搜索字段的选择和光标位置等。
我真正的问题是,是否有更好,更正确,更自动的方式来保存和恢复搜索字段的状态?或者我是否需要为我希望保存的搜索字段的每个属性编写自己的代码?
我试过用:
searchField.encodeRestorableState(with: coder)
和:
searchField.restoreState(with: coder)
在上述两种方法中,但在我的应用重新启动时,搜索字段中没有出现任何内容。
我还实施了:
override class func restorableStateKeyPaths() -> [String] { var keys = super.restorableStateKeyPaths() keys.append("searchField.stringValue") return keys }
其中“searchField”是视图控制器中NSTextField outlet属性的名称。启动我的应用程序但在搜索字段中未恢复文本时会调用此方法。
此视图控制器是从故事板创建的。视图控制器的标识符已设置。搜索字段的标识符也已设置。此视图控制器是另一个视图控制器的子视图控制器。
我已经阅读了“核心应用程序设计”文档的User Interface Preservation部分,但不清楚视图控制器的视图是如何保存/恢复的,以及有多少是自动与手动的。
支持OSX 10.12和10.11。任何答案中的Objective-C或Swift都可以。
import Cocoa class RestoredWindow: NSWindow { override class var restorableStateKeyPaths: [String] { return ["self.contentViewController.searchField.stringValue"] } }
将此自定义类分配给Identity Inspector中的Window Controller。
接下来,让我们将searchField.stringValue属性绑定到Bindings Inspector的Value部分中的ViewController。
import Cocoa class ViewController: NSViewController { @IBOutlet weak var searchField: NSSearchField! override func viewDidLoad() { super.viewDidLoad() } }
After this,make sure you haven’t checked
Close windows when quitting an app
option in yourSystem Preferences
->General
tab.
现在,在退出并再次启动应用程序后,NSSearchField中输入的文本已恢复。
附:
我尝试过的方式和你一样,但也失败了。这种方法对我不起作用:
override func encodeRestorableState(with coder: NSCoder) { coder.encode(searchField.stringValue,forKey: "restore") super.encodeRestorableState(with: coder) } override func restoreState(with coder: NSCoder) { if let state = coder.decodeObject(forKey: "restore") as? NSSearchField { searchField.stringValue = state } super.restoreState(with: coder) }