如何在UICollectionViewCell中实现复制键盘快捷键支持?
核心原因
copy(_:) 与 printContent(_:) 虽同属UIKit标准响应者方法,但二者在iPadOS快捷键浮层的识别逻辑存在差异:
printContent(_:)属于打印类系统动作,只要响应者实现对应方法、Info.plist配置了打印权限声明、当前响应者处于响应者链上,就会被识别为可用快捷键copy(_:)属于剪切板编辑类动作,UIKit对这类动作有额外校验规则,默认状态下UICollectionViewCell不会通过这类动作的校验,因此即使实现了方法也不会出现在快捷键列表中
必要配置步骤
要让聚焦状态的UICollectionViewCell支持Command+C复制快捷键,需要完成三项配置:
- 重写cell的第一响应者权限
自定义UICollectionViewCell子类中重写canBecomeFirstResponder属性,返回true:override var canBecomeFirstResponder: Bool { true } - 显式声明支持copy动作
UIKit不会仅通过方法存在就判定编辑类动作可用,必须重写canPerformAction(_:withSender:)方法,对copy动作返回可用状态:
这里增加override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { if action == #selector(copy(_:)) { // 可根据业务逻辑加额外判断,比如当前是否存在可复制内容 return isFocused } return super.canPerformAction(action, withSender: sender) }isFocused判断是为了保证只有当前聚焦高亮的cell响应copy动作,避免多个响应者同时声明支持该动作导致系统识别异常。 - 聚焦时主动触发第一响应者切换
重写cell的聚焦回调方法,在cell进入聚焦状态时主动成为第一响应者,失焦时释放第一响应者:override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { super.didUpdateFocus(in: context, with: coordinator) if isFocused { becomeFirstResponder() } else { resignFirstResponder() } }
异常排查:如果完成上述配置后仍不生效,检查UICollectionView的
allowsSelection属性是否为false,部分iPadOS版本中UICollectionView会在禁止选中状态下拦截所有编辑类动作,此时可重写UICollectionView的canPerformAction(_:withSender:)方法,不对copy动作做拦截,让事件顺着响应者链传递给当前聚焦的cell即可。
内容的提问来源于stack exchange,提问作者Jordan H
相关产品推荐
相关产品推荐

