How do I register UndoManager in Swift?

后端 未结 7 976
温柔的废话
温柔的废话 2020-12-09 19:43

How do I use UndoManager (previously NSUndoManager) in Swift?

Here\'s an Objective-C example I\'ve tried to replicate:

[[un         


        
7条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-09 20:08

    I tried for 2 days to get Joshua Nozzi's answer to work in Swift 3, but no matter what I did the values were not captured. See: NSUndoManager: capturing reference types possible?

    I gave up and just managed it myself by keeping track of changes in undo and redo stacks. So, given a person object I would do something like

    protocol Undoable {
         func undo()
         func redo()
    }
    
    class Person: Undoable {
    
        var name: String {
            willSet {
                 self.undoStack.append(self.name)
            }
        }
        var undoStack: [String] = []
        var redoStack: [String] = []
    
        init(name: String) {
            self.name = name
        }
    
        func undo() {
            if self.undoStack.isEmpty { return }
            self.redoStack.append(self.name)
            self.name = self.undoStack.removeLast()
        }
    
        func redo() {
            if self.redoStack.isEmpty { return }
            self.undoStack.append(self.name)
            self.name = self.redoStack.removeLast()
        }
    }
    

    Then to call it, I don't worry about passing arguments or capturing values since the undo/redo state is managed by the object itself. So say you have a ViewController that is managing your Person objects, you just call registerUndo and pass nil

    undoManager?.registerUndo(withTarget: self, selector:#selector(undo), object: nil)
    

提交回复
热议问题