【问题标题】:How to disable default keyboard navigation in Mac Catalyst app?如何在 Mac Catalyst 应用程序中禁用默认键盘导航?
【发布时间】:2020-04-10 20:06:55
【问题描述】:

我注意到,在 Mac Catalyst 应用程序中,我可以通过按 Mac 键盘上的向上和向下箭头键来逐行浏览 UITableView 中的行。但是,这会干扰我的一个视图控制器中的现有功能。有没有办法禁用它?

我在UITableView 文档中找不到对此功能的任何引用。 Mac Catalyst 的Human Interface Guidelines 提到“自动支持基本的 Mac 功能,例如 ... 键盘导航”,所以我想这是一个有意的功能,但我找不到任何进一步的参考或文档。

我没有在我的应用程序中看到任何其他“自动”键盘导航示例,但理想情况下,Apple 会发布一个完整列表,以便我们知道如何使用,或者如果需要,禁用内置功能。

【问题讨论】:

    标签: ios macos uitableview keyboard-shortcuts mac-catalyst


    【解决方案1】:

    自 2021 年 11 月 6 日起更新

    看起来 Apple 一直在改变默认焦点系统的工作方式,而我之前的解决方案不再有效或不再需要。

    UIKeyCommand 有一个新的wantsPriorityOverSystemBehavior: Bool 属性,需要将其设置为true,以便我们的子类接收某些类型的命令,包括箭头键命令。

    至少从 Xcode 13.1 和 macOS 11.6 开始,也许更早,我们现在可以简单地将以下内容添加到 UITableViewController 子类中,以使用自定义键盘导航处理替换默认焦点行为:

    class TableViewController: UITableViewController {
        override var keyCommands: [UIKeyCommand]? {
            let upArrowCommand = UIKeyCommand(
                input: UIKeyCommand.inputUpArrow,
                modifierFlags: [],
                action: #selector(handleUpArrowKeyPress)
            )
            upArrowCommand.wantsPriorityOverSystemBehavior = true
            
            let downArrowCommand = UIKeyCommand(
                input: UIKeyCommand.inputDownArrow,
                modifierFlags: [],
                action: #selector(handleDownArrowKeyPress)
            )
            downArrowCommand.wantsPriorityOverSystemBehavior = true
            
            return  [
                upArrowCommand,
                downArrowCommand
            ]
        }
    
        @objc
        func handleUpArrowKeyPress () {
        }
    
        @objc
        func handleDownArrowKeyPress () {
        }
    }
    

    以前的答案(不再有效或不需要)

    Catalyst 自动将向上/向下箭头的 UIKeyCommands 分配给 UITableView 实例。这在 iOS 上不会发生。您可以通过在UITableViewControllerviewDidLoad() 中设置断点并检查tableView.keyCommands 来查看此操作。

    所以我创建了一个非常简单的 UITableView 子类并通过返回 nil 禁用了默认的 keyCommmands

    class KeyCommandDisabledTableView: UITableView {
        override var keyCommands: [UIKeyCommand]? {
            return nil
        }
    }
    

    然后我更新了我的UITableViewController 子类以使用新的KeyCommandDisabledTableView 子类:

    class MyTableViewController: UITableViewController {
        override func loadView() {
            self.view = KeyCommandDisabledTableView(
                frame: .zero, 
                style: .plain // or .grouped
            )
        }
    }
    

    等等!默认箭头键处理已消失,现在正在调用我的应用的自定义箭头键处理。

    【讨论】:

    • 我尝试使用它,因为我的 resignFirstResponder 解决方案在 macOS 11.5 中停止工作。首先,我必须在UITableView 子类中添加canBecomeFirstResponder=true,否则它的keyCommands 将不会被调用。但即使这样做,默认的键盘命令仍在运行。我确认tableView.keyCommands 之前有向上/向下箭头命令,现在为零,所以我不知道默认命令来自哪里。此解决方案是否仍然适合您?
    • @arlomedia 请查看我的更新答案,如果这对您有用,请告诉我。我已经在 macOS 11.6、macOS 12 和 iOS 15 上的示例项目中对其进行了测试。
    • 感谢您的更新!这对我有用,但表中的第一行有时仍会突出显示。我刚刚发布了一个从 Apple DTS 票证中获得的更简单的解决方案。
    • 谢谢@arlomedia!
    【解决方案2】:

    这是我从 Apple DTS 收到的另一个解决方案。只需将其添加到表视图委托:

    func tableView(_ tableView: UITableView, canFocusRowAt indexPath: IndexPath) -> Bool {
        return false
    }
    

    这适用于 macOS 11.6 和 12.0。我没有要测试的 10.15 或 11.5 Mac,所以我也会保留我之前的 resignFirstResponder 解决方案。

    【讨论】:

      【解决方案3】:

      我进一步注意到默认箭头键导航仅在单击表格中的一行后开始,所以我猜该表格必须承担第一响应者角色。我将此添加到我的表的委托类中:

      - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
          #if TARGET_OS_MACCATALYST
          [tableView performSelector:@selector(resignFirstResponder) withObject:nil afterDelay:0.1];
          #endif
      }
      

      这解决了它!现在默认键盘导航一打开就会关闭,并且不会干扰我应用的自定义键盘导航。

      (没有延迟就不行了。)

      【讨论】:

      • 此解决方案在 macOS 11.5 中停止为我工作。
      【解决方案4】:

      借助 UITableView 和 UICollectionView 的 selectionFollowsFocus 属性,iOS 14 / macOS 11 可以更轻松地禁用此行为:

      tableView.selectionFollowsFocus = false
      

      【讨论】:

      • 遗憾的是,这对我没有任何影响。 (我尝试在加载/显示表格之前和之后调用它。)
      猜你喜欢
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      相关资源
      最近更新 更多