覆盖 UITextView 的 CMD + Z 键命令
Override UITextView's CMD + Z key command
是否可以覆盖 UITextView
对 cmd + z
和 cmd + shift + z
的处理?
我试过了
- 覆盖
keyCommand
属性,但永远不会调用选择器..
- 覆盖
undoManager
,这也无济于事
class CustomTextView: UITextView {
override var keyCommands: [UIKeyCommand]? {
[
// cmd + z (doesn't work)
UIKeyCommand(input: "z", modifierFlags: [.command], action: #selector(undo)),
// cmd + shift + z (doesn't work)
UIKeyCommand(input: "z", modifierFlags: [.command, .shift], action: #selector(redo)),
// z (works)
UIKeyCommand(input: "z", modifierFlags: [], action: #selector(z)),
]
}
// this doesn't help
override var undoManager: UndoManager? { return nil }
// undo
@objc private func undo() {
print("undo")
}
// redo
@objc private func redo() {
print("redo")
}
// z
@objc private func z() {
print("z")
}
}
您可以使用 UITextView+UIResponder.swift 扩展来做到这一点:
import UIKit
extension UITextView {
static var myUndoManager = UndoManager()
fileprivate func handleUndo () { ... }
fileprivate func handleRedo () { ... }
override var undoManager : UndoManager? {
return Self.myUndoManager
}
override func pressesBegan (
_ presses: Set<UIPress>
, with event: UIPressesEvent?
)
{
for press in presses {
guard
let key = press.key
, key.charactersIgnoringModifiers == "z"
else { continue }
switch key.modifierFlags {
case .command:
handleUndo()
case [ .command, .shift]:
handleRedo()
default:
break
}
}
super.pressesBegan (
presses
, with: event
)
}
}
相关 Apple 参考资料:
UIResponder::func pressesBegan(_:)
https://developer.apple.com/documentation/uikit/uiresponder
Keyboards & Input::class UIKey
https://developer.apple.com/documentation/uikit/uikey
另请参阅:uiresponder
https://whosebug.com/questions/tagged/uiresponder
为什么覆盖 keyCommands
不起作用?
UITextView 是不透明的,所以我自己看不到,但我认为它会覆盖 pressesBegan(_:with:)
并且不会为它处理的任何按键调用 super
。如果没有对 super
的调用,UIPressesEvent
事件永远不会向上传播响应者链; keyCommands
永远不会看到他们。
是否可以覆盖 UITextView
对 cmd + z
和 cmd + shift + z
的处理?
我试过了
- 覆盖
keyCommand
属性,但永远不会调用选择器.. - 覆盖
undoManager
,这也无济于事
class CustomTextView: UITextView {
override var keyCommands: [UIKeyCommand]? {
[
// cmd + z (doesn't work)
UIKeyCommand(input: "z", modifierFlags: [.command], action: #selector(undo)),
// cmd + shift + z (doesn't work)
UIKeyCommand(input: "z", modifierFlags: [.command, .shift], action: #selector(redo)),
// z (works)
UIKeyCommand(input: "z", modifierFlags: [], action: #selector(z)),
]
}
// this doesn't help
override var undoManager: UndoManager? { return nil }
// undo
@objc private func undo() {
print("undo")
}
// redo
@objc private func redo() {
print("redo")
}
// z
@objc private func z() {
print("z")
}
}
您可以使用 UITextView+UIResponder.swift 扩展来做到这一点:
import UIKit
extension UITextView {
static var myUndoManager = UndoManager()
fileprivate func handleUndo () { ... }
fileprivate func handleRedo () { ... }
override var undoManager : UndoManager? {
return Self.myUndoManager
}
override func pressesBegan (
_ presses: Set<UIPress>
, with event: UIPressesEvent?
)
{
for press in presses {
guard
let key = press.key
, key.charactersIgnoringModifiers == "z"
else { continue }
switch key.modifierFlags {
case .command:
handleUndo()
case [ .command, .shift]:
handleRedo()
default:
break
}
}
super.pressesBegan (
presses
, with: event
)
}
}
相关 Apple 参考资料:
UIResponder::func pressesBegan(_:)
https://developer.apple.com/documentation/uikit/uiresponder
Keyboards & Input::class UIKey
https://developer.apple.com/documentation/uikit/uikey
另请参阅:uiresponder https://whosebug.com/questions/tagged/uiresponder
为什么覆盖 keyCommands
不起作用?
UITextView 是不透明的,所以我自己看不到,但我认为它会覆盖 pressesBegan(_:with:)
并且不会为它处理的任何按键调用 super
。如果没有对 super
的调用,UIPressesEvent
事件永远不会向上传播响应者链; keyCommands
永远不会看到他们。