NSViewController 用户界面状态恢复
Posted
技术标签:
【中文标题】NSViewController 用户界面状态恢复【英文标题】:NSViewController User Interface State Restoration 【发布时间】:2016-12-12 15:38:31 【问题描述】:总结:
使用 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
插座属性的名称。当我的应用程序启动但文本未在搜索字段中恢复时调用此方法。
这个视图控制器是从故事板创建的。视图控制器的identifier
已设置。搜索字段的identifier
也已设置。这个视图控制器是另一个视图控制器的子视图控制器。
我已通读“核心应用程序设计”文档的 User Interface Preservation 部分,但不清楚如何保存/恢复视图控制器的视图,以及其中有多少是自动的还是手动的。
支持 OSX 10.12 和 10.11。任何答案中的 Objective-C 或 Swift 都可以。
【问题讨论】:
“或者,您的自定义响应者对象可以覆盖restorableStateKeyPaths
方法并使用它来指定要保留的任何属性的关键路径。Cocoa 使用关键路径来定位和保存数据对应的属性。属性必须符合键值编码和键值观察。"?
@LeoNatan 我刚试过。我在视图控制器中实现了该方法并返回了NSTextField
属性的名称。该方法被调用,但文本字段未恢复。
我认为它应该包含密钥路径的.stringValue
部分。它应该深入到值本身,而不是控件。
@LeoNatan 不,那也没用。我更新了该代码以返回"searchField.stringValue"
。
如果您在恢复之前自己设置stringValue
,则恢复过程似乎不会被存储值覆盖。 “使用+restorableStateKeyPaths
时不需要上述步骤,因为 KVO 会为我们处理。” bignerdranch.com/blog/cocoa-ui-preservation-yall
【参考方案1】:
为了实现上述效果,让我们创建NSSearchField
和一个名为RestoredWindow
的自定义类,其中只包含一个属性:
import Cocoa
class RestoredWindow: NSWindow
override class var restorableStateKeyPaths: [String]
return ["self.contentViewController.searchField.stringValue"]
将此自定义类分配给 Identity Inspector 中的 Window Controller。
接下来,让我们在 Bindings Inspector 的 Value
部分将 searchField.stringValue
属性绑定到 ViewController
。
import Cocoa
class ViewController: NSViewController
@IBOutlet weak var searchField: NSSearchField!
override func viewDidLoad()
super.viewDidLoad()
在此之后,请确保您没有选中
System Preferences
->General
标签中的Close windows when quitting an app
选项。
现在,在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)
【讨论】:
以上是关于NSViewController 用户界面状态恢复的主要内容,如果未能解决你的问题,请参考以下文章
从 NSTableView 获取数据到 NSViewController
如何在 Mac OS X 应用程序中从一个 NSViewcontroller 推送到另一个 NSViewcontroller?