为什么我的 SwiftUI iPhone 应用程序具有抖动撤消功能,可同时撤消自定义操作和 TextField 更改?

Why is my SwiftUI iPhone app with shake-to-undo undoing custom actions and TextField changes at the same time?

提问人:Graham Lea 提问时间:5/15/2023 最后编辑:Graham Lea 更新时间:5/15/2023 访问量:72

问:

我正在构建一个 SwiftUI iPhone 应用程序。我通过监听主服务器上的抖动并调用方法设置了一些撤消行为,这些方法有时会注册我自己的操作。ViewUndoManager

以下是主要代码中的一些代码:View

    @Environment(\.undoManager) private var undoManager: UndoManager!
        .onReceive(
            NotificationCenter.default.publisher(for: UIDevice.deviceDidShake),
            perform: handleShake
        )
    private func handleShake(_: Any) {
        if let undoManager = undoManager {
            if undoManager.canUndo {
                undo()
            } else if undoManager.canRedo {
                redo()
            }
        }
    }

这一切都有效,但我有一个奇怪的情况:

  1. 执行一些注册自定义操作的操作(例如,将 TODO 标记为“完成”)
  2. 聚焦于并编辑它TextField
  3. 摇晃手机

然后发生的情况是,其中的编辑都被撤消了,自定义操作也被撤消了!TextField

调试打印语句确认仅检测到一次抖动。

我尝试注释掉我的自定义抖动处理,以防 iOS 已经在处理文本字段本身的抖动以撤消,但事实并非如此。如果没有我的代码将 shake 连接到 ,则不会在 shake 时撤消编辑。UndoManagerTextField

另一个有趣的数据点是,如果我没有使用 注册任何自定义撤消操作,然后编辑 ,然后是,所以抖动不会撤消任何操作。我什至调用了 when is false,这对 TextField 没有任何作用!UndoManagerTextFieldUndoManager.canUndofalseundoManager.undo()canUndo

因此,任何指向我可能做错了什么的帮助,或者我不明白撤消应该在 SwiftUI 中如何工作,将不胜感激!

编辑:代码的这一部分也可能是相关的。这是对的吗?它是否也应该以某种方式调用实现?overridesuper

extension UIDevice {
    static let deviceDidShake = Notification.Name("deviceDidShake")
}


extension UIWindow {
    open override func motionEnded(_ motion: UIEvent.EventSubtype, with: UIEvent?) {
        guard motion == .motionShake else { return }
        NotificationCenter.default.post(name: UIDevice.deviceDidShake, object: nil)
    }
}
iOS SwiftUI 撤消 nsundomanager

评论


答: 暂无答案