【问题标题】:Tabbing between NSTextFields with nextKeyView使用 nextKeyView 在 NSTextFields 之间切换
【发布时间】:2017-05-12 17:44:03
【问题描述】:

我有一个具有以下布局的 NSViewController,使用情节提要设置:

每个 NSTextField 的 nextKeyView 出口被配置为屏幕截图中显示的顺序中的下一个 NSTextField。例如,我在 IB 中选择了服务器 NSTextField,并从 Connectivity inspector 中的 nextKeyView 出口拖到了登录 NSTextField,其余字段也是如此。

当应用程序启动时,任何字段上的任何选项卡都会将选择移动到第一个 NSTextField。如何在字段之间实现所需的制表符?

我在相应的 WindowController 中尝试过,但无济于事:

- (void)windowDidLoad {
    [super windowDidLoad];

    self.window.initialFirstResponder = self.serverTextField;
}

【问题讨论】:

  • 你设置了windows的initialFirstResponder吗?
  • @catlan 更新了问题
  • 确保您的 NSWindowController 子类 -windowDidLoad 中没有任何内容是 nil。即检查窗口、self.contentViewController 和文本字段:ViewController *vc = (ViewController *)self.contentViewController; self.window.initialFirstResponder = vc.field1;

标签: macos cocoa interface-builder nstextfield nsviewcontroller


【解决方案1】:

这似乎是最详细的 answer,来自 Justin Bur 发布到 cocoa-dev 邮件列表(2007 年 1 月 31 日)。

多年来,人们曾多次问为什么他们的密钥 视图循环无法正常工作。大多数这些查询永远不会得到 在名单上回答。在未能为我的关键视图循环找到帮助之后 这个列表或网站上的问题,我做了一些 实验。

关键视图循环可能难以处理。它旨在 只是神奇地工作,所以在大多数情况下这不是问题。但如果它 不工作,很难弄清楚为什么不工作。这里是 获得工作键视图循环的一些指南。

  1. 考虑您是否可以接受自动生成的键视图循环。每个响应者的左上角决定其位置 在循环。循环从左上到右下,逐行 行(至少对于从左到右的脚本)。这是迄今为止最简单的 解决方案。要启用此功能,请确保窗口的 initialFirstResponder 。另见-[NSWindow recalculateKeyViewLoop]

  2. 如果自动键视图循环不合适,请尽可能使用 Interface Builder 设置您自己的键视图循环。窗户的 initialFirstResponder outlet 必须设置,以禁用 自动密钥循环生成。从那个循环周围的响应者, 设置循环中每个项目的nextKeyView 出口。 (如果需要, 最后一项的nextKeyView可以设置为第一项,从而关闭 循环。)对于任何带有滚动条的视图(NSTextViewNSTableView 等), 设置nextKeyView 时应使用封闭的NSScrollView

  3. 如果您在代码中创建了任何响应程序,请尽早将它们拼接到关键视图循环中(最好在awakeFromNib 或者-[NSWindowController windowDidLoad])。 对于每个(序列)新项目,您必须使用 call -[NSView setNextKeyView:] 因此:一次 上一个项目指向(第一个)新项目,(调用每个 新项目指向下一个),最后使(最后一个)新项目 指向它的继任者。

  4. 如果您的窗口有工具栏,有兴趣成为关键视图的工具栏项目将自动添加和删除自己作为 工具栏显示或隐藏。工具栏不考虑 -[NSWindow autorecalculatesKeyViewLoop] 的返回值。工具栏项目 总是放在最左上角项目之前的循环中。有 没有简单的方法来改变这一点。

  5. 一旦显示了窗口,就很难修改键视图循环 - 特别是如果您正在使用 NSScrollViewNSTabView。这些(和其他?)是特殊情况 因为它们会自动将包含的视图插入到循环中。 有关 initialFirstResponder 和关键视图循环的信息 NSTabViewItem,请参阅 OS X 10.1 的 AppKit 发行说明 .

  6. 如果您的项目有时应该在循环中,而其他时候不应该,则不建议尝试将它们拼接进出 循环。相反,将-[NSResponder acceptsFirstResponder] 子类化为 这些项目。如果一个项目从此方法返回 NO,它将被留下 脱离循环(暂时);如果返回YES,它会返回 进入循环。或者,如果项目源自 NSControl(它 可能是),你可以拨打setRefusesFirstResponder:就可以了。

  7. 如果您犯了一个错误,您的按键视图循环将在一个方向或两个方向停止运行。一旦它破裂,它就会一直破裂。到 调试,注释掉对setNextKeyView:的调用或 setInitialFirstResponder: 直到它再次工作。有问题的电话是 可能试图在存在的情况下修改键视图循环 NSScrollViewNSTabView,在这些对象已经完成它们之后 幕后循环。将呼叫移至较早的点,或 不用。 (如果您没有致电setNextKeyView:,请检查您的 笔尖 - 确保设置了窗口的initialFirstResponder 并且 nextKeyView 出口以您想要的方式链接在一起。)

  8. 在系统偏好设置/键盘和鼠标/键盘快捷键中,在“全键盘访问”下的窗格底部,您可以控制 关键视图循环是否包含所有控件或仅包含文本字段和 滚动列表(^F7 切换)。你应该测试你的关键视图循环 在每个状态下使用此设置。

这些准则是通过实验确定的,可能并不完全 准确的。欢迎更正和进一步解释。

【讨论】:

  • 这是一个彻底的答案,但对我的情况没有帮助。我有一个基于 ViewController 的响应者链;更改 WindowController 中的任何内容似乎都没有帮助。
  • 值得一提的是NSWindowautorecalculatesKeyViewLoop属性,这是我最终使用的。
  • @aleclarson 你应该把你的评论变成一个答案。如果你这样做,我会投票赞成,因为这也解决了我的问题。
【解决方案2】:

在窗口控制器的windowDidLoad或视图控制器的viewWillAppear中设置窗口的initialFirstResponder。如果在窗口的makeKeyAndOrderFront 之前没有设置initialFirstResponder,则调用recalculateKeyViewLoop

【讨论】:

    猜你喜欢
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2020-04-01
    • 2015-09-23
    相关资源
    最近更新 更多