我遇到的问题UndoManager
可能是 iPadOS 错误,但也可能是我的错误。
我有一个简单的测试应用程序。一个按钮执行一个操作,它将 int 增加 1 并向系统注册一个 undo UndoManager
。另一个按钮手动调用undoManager.undo()
,它撤消最后一个操作,直到撤消堆栈上没有更多操作。并且整个应用程序是系统的第一响应者,因此点击也应该触发 undoManager每按 CMD+ZCMD+Z
调用一次。undo()
这是一些代码。
允许成为第一响应者的 UIHostingController 子类:
class FirstResponderHostingController<Content: View>: UIHostingController<Content> {
override var canBecomeFirstResponder: Bool { true }
}
SceneDelegate,我传入系统撤消管理器的地方:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
let model = MyObject(undoManager: window.undoManager)
let contentView = ContentView(model: model)
window.rootViewController = FirstResponderHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
//...
}
还有我的 SwiftUI 视图和相关模型:
class MyObject: ObservableObject {
var undoManager: UndoManager?
var state: Int = 0
init(undoManager: UndoManager? = nil) {
self.undoManager = undoManager
}
func registerAction() {
state += 1
undoManager?.registerUndo(withTarget: self, selector: #selector(performUndo), object: nil)
print("registered action - state is \(state)")
}
@objc func performUndo() {
state -= 1
print("performUndo called - state is \(state)")
}
func undo() {
print("undo() called")
undoManager?.undo()
}
}
struct ContentView: View {
@ObservedObject var model: MyObject
var body: some View {
VStack(spacing: 16) {
Button(action: {
self.model.registerAction()
}) {
Text("Register an Action")
}
Button(action: {
self.model.undo()
}) {
Text("Manual Undo (Not from Keyboard)")
}
}
}
}
例如,如果我点击“注册操作”两次,然后点击“手动撤消”三次,输出就是我所期望的 - 状态增加了两次,然后减少了两次,最后一个 undo() 什么也不做,因为撤消堆栈为空:
registered action - state is 1
registered action - state is 2
undo() called
performUndo called - state is 1
undo() called
performUndo called - state is 0
undo() called
但是,如果我点击“注册操作”两次,然后点击CMD+Z
iPad 键盘,我希望状态会增加两次,并且只减少一次,一次调用performUndo
,但performUndo
仍然被调用两次:
registered action - state is 1
registered action - state is 2
performUndo called - state is 1
performUndo called - state is 0
我是否以某种方式错误地使用了系统 UndoManager,或者这是一个错误?
更新:以上内容适用于 Xcode 11.3.1 和 iPadOS 13.3。使用最新的 Xcode 11.4 beta 2 和 iPadOS 13.4 beta 2,不再发生双重撤销。似乎固定!