首页 > 解决方案 > iOS 中的 UndoManager 持久化

问题描述

我想在我的应用程序中实现撤消/重做操作。需要为每个文档而不是在 UIViewController 级别记录撤消/重做操作。所以我需要将 UndoManager 放在实现自定义文档的类中。但其中一项要求是即使重新启动应用程序也应该可以撤消/重做,这意味着 UndoManager 必须是持久的。我们如何使 UndoManager 状态持久化?

标签: iosswiftnsundomanager

解决方案


据我所知, UndoManager 与您的数据模型没有直接关系,因此与您的应用程序状态(即数据模型状态)没有直接关系。它仅允许您注册一些将以撤消/重做方式更改数据模型的操作。为了实现持久性,在使用 UndoManager 时,您必须使用一些持久性存储(像 Core Data 或 Realm 这样的数据库,或者对于非常简单的状态,您可以使用 UserDefaults)。您必须执行向 UndoManager 注册的操作,以更新您选择使用的持久存储。此外,您必须以某种方式跟踪数据库中的更改,以便在应用程序启动之间恢复和注册它们。

我在网上找到了一个描述撤消/重做操作注册的示例 - 取自此示例 - https://medium.com/flawless-app-stories/undomanager-in-swift-5-with-simple-example-8c791e231b87

//MARK:- Add/Remove Student : Undo/Redo Actions
// Register inverse Actions that automatically performs
extension StudentsListViewController {
  func addNewStudentUndoActionRegister(at index: Int){
    self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
      selfTarget.removeNewStudent(at: index)
      selfTarget.removeNewStudentUndoActionRegister(at: index)
    })
  }
  
  func removeNewStudentUndoActionRegister(at index: Int){
    self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
      selfTarget.addNewStudent(at: index)
      selfTarget.addNewStudentUndoActionRegister(at: index)
    })
  }
}

如您所见,动作只会改变状态,而 UndoManager 不会跟踪状态,只是动作......

一些个人意见:对于复杂的逻辑和状态,我个人喜欢使用一些状态管理框架,比如 Redux(或 Swift 等效的 ReSwift),在这种情况下,我可以轻松创建 Undo/Redo 动作。您可以轻松地记录应用程序生命周期中的状态,并将其记录到持久存储中,例如,使您的状态可编码并将其堆栈保存在存储中。它有点使用 UndoManager 的目的——但据我所知,您不能将注册的操作保存到磁盘。


推荐阅读