NSTextView:在故事板应用程序中辞职第一响应者
Posted
技术标签:
【中文标题】NSTextView:在故事板应用程序中辞职第一响应者【英文标题】:NSTextView: Resign First Responder in storyboard app 【发布时间】:2017-06-24 00:05:15 【问题描述】:我有一个使用故事板(OSX 10.12;Xcode 9)的 macOS 应用程序。我感兴趣的视图控制器嵌入在拆分视图控制器中,拆分视图控制器嵌入在拆分视图控制器中,拆分视图控制器是主视图控制器的内容视图控制器,因此它位于三层深度。
在这个视图控制器中,我有一个 NSTextField(“title”)和一个 NSTextView(“body”)。无论我做什么,NSTextView 都是第一响应者,我希望我的 NSTextField 成为用户输入的第一个项目。
我尝试过使用 NSApplication.shared.mainWindow?.makeFirstResponder(title) 在 ViewWillAppear 中(在 ViewDidLoad 中 mainWindow 仍然为零;谢谢,Storyboard)但它没有任何效果:调用它之后,body 仍然是第一响应者。
使用 body.resignFirstResponder() 或 title.becomeFirstResponder() 同样没有任何效果(我知道文档说“永远不要直接调用此方法”,但必须尝试);光标在文本视图中继续愉快地闪烁。
我设法通过子类化 NSTextView 创建了一个 hack,最初从“acceptsFirstResponder”返回 false,然后在我的 ViewController 的 viewDidLoad 方法中将其设置回“true”,但这很丑陋,而且只是回避了响应者链。
当 NSTextView 不想接受提示时,将我的 NSTextField 设置为第一响应者的正确方法是什么?
【问题讨论】:
NSTextField 是否在 NSTextView 之上?你对他们做了什么,设置内容,绑定或什么?你有没有尝试设置窗口的initialFirstResponder
?
TextField 位于 TextView 的上方和左侧,这没有任何区别。我在 ViewDidLoad 中设置内容;我刚刚颠倒了顺序,但这没有什么区别。 initialFirstResponder 是一个有趣的——我不知道。我在 ViewWillAppear 中设置了它(这似乎是我可以访问窗口的第一个位置),虽然它会在控制台中告诉我我的 textField 是最初的第一响应者,但光标在 textView 中愉快地闪烁。跨度>
我无法重现您的问题,它一定是您在某个地方做了什么。
我现在玩得更多了,当问题出在其他地方时,我可能会责怪 NSTextView:如果我在情节提要的 ViewController 中添加两个 NSTextField,首先添加的是第一响应者,无论我做什么。
这似乎是一个时间问题 - 如果我在窗口控制器中添加此代码,并在 windowDidLoad 中设置 initialFirstResponder,它工作正常。但是请参见上面的回复:“故事板的三个层次”,我显然缺少一些东西。
【参考方案1】:
我所有尝试设置第一响应者的真正问题是我绝对没有做错任何事情:在 ViewWillLoad 中调用的 NSApplication.shared.mainWindow?.makeFirstResponder(title) 似乎正是需要调用的方法正确的时间。
也就是说,除非窗口设置为“可恢复”,这在 Xcode 8/9 中是默认设置。 (这让我有些困惑。文档说“如果您将窗口标记为可恢复,则必须将恢复类与它们相关联。”;默认情况下未设置,它比起初听起来要复杂一些。(请参阅https://www.raywenderlich.com/117471/state-restoration-tutorial 获取 ios 教程;我会看看其中有多少适用于 macOS)。)
除了窗口位置和大小之外,确实在启动之间保留的一件事是当您退出应用程序时哪个界面元素处于活动状态;将 window.isRestorable 设置为 false,initialFirstResponder 会像宣传的那样工作。
这是一个稍微不令人满意的答案,但听起来像是这些“预期行为”问题之一,所以我可能不得不忍受完全无法确定启动时哪个文本元素处于活动状态。 (无论哪种方式我都可以看到用例,但窗口恢复有足够的优势,我很可能会采用它。)
【讨论】:
以上是关于NSTextView:在故事板应用程序中辞职第一响应者的主要内容,如果未能解决你的问题,请参考以下文章
NSPersistentDocument 中的 NSTextView 在失去第一响应者之前不会更新脏标志