如何在 Mac Catalyst 应用程序中禁用默认键盘导航?
Posted
技术标签:
【中文标题】如何在 Mac Catalyst 应用程序中禁用默认键盘导航?【英文标题】:How to disable default keyboard navigation in Mac Catalyst app? 【发布时间】:2020-04-10 20:06:55 【问题描述】:我注意到,在 Mac Catalyst 应用程序中,我可以通过按 Mac 键盘上的向上和向下箭头键来逐行浏览 UITableView
中的行。但是,这会干扰我的一个视图控制器中的现有功能。有没有办法禁用它?
我在UITableView 文档中找不到对此功能的任何引用。 Mac Catalyst 的Human Interface Guidelines 提到“自动支持基本的 Mac 功能,例如 ... 键盘导航”,所以我想这是一个有意的功能,但我找不到任何进一步的参考或文档。
我没有在我的应用程序中看到任何其他“自动”键盘导航示例,但理想情况下,Apple 会发布一个完整列表,以便我们知道如何使用,或者如果需要,禁用内置功能。
【问题讨论】:
【参考方案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 上不会发生。您可以通过在UITableViewController
的viewDidLoad()
中设置断点并检查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
【讨论】:
遗憾的是,这对我没有任何影响。 (我尝试在加载/显示表格之前和之后调用它。)以上是关于如何在 Mac Catalyst 应用程序中禁用默认键盘导航?的主要内容,如果未能解决你的问题,请参考以下文章