Реализуйте отмену / повтор в шаблоне команды, используя NSUndomanager в Swift - PullRequest
0 голосов
/ 18 апреля 2019

Я пытаюсь реализовать функцию отмены / возврата в простой программе рисования / рисования, которую я пишу для macOS в Swift. Я столкнулся с NSUndoManager, но не могу заставить его работать в сочетании с моим Command-Pattern (протокол реализован в программе)

У меня для протокола команды реализован следующий протокол:

import Foundation

protocol Command {
    func execute()

    func unexecute()
}

Я упростил свой ViewController для краткости и ясности вопроса:

Мой ViewController:

class ViewController: NSViewController {
    var brect = true
    var startPoint: NSPoint?
    var endPoint: NSPoint?

    lazy var window: NSWindow = self.view.window!
    var mouseLocation: NSPoint {
        return NSEvent.mouseLocation
    }

    var location: NSPoint {
        return window.mouseLocationOutsideOfEventStream
    }

    override func mouseDown(with event: NSEvent) {
        startPoint = event.locationInWindow
    }

    override func mouseUp(with event: NSEvent) {
        endPoint = event.locationInWindow

        let x = min(endPoint!.x, startPoint!.x)
        let y = min(endPoint!.y, startPoint!.y)
        let w = abs((endPoint?.x)! - (startPoint?.x)!)
        let h = abs((endPoint?.y)! - (startPoint?.y)!)

        let positions = NSMakeRect(0, 0, 0, 0)

        DrawShape(x: x, y: y, w: w, h: h, positions: positions, drawRect: brect, view: view).execute()
    }

    class DrawShape: Command {
        let x: CGFloat
        let y: CGFloat
        let w: CGFloat
        let h: CGFloat
        let positions: NSRect
        let brect: Bool
        let v: NSView

        init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, positions: NSRect, drawRect: Bool, view: NSView) {
            self.x = x
            self.y = y
            self.w = w
            self.h = h
            self.positions = positions
            brect = drawRect
            v = view
        }

        func execute() {
            let frame = NSRect(x: x, y: y, width: w, height: h)

            if frame.width > 0, frame.height > 0 {
                Drawing(frame: frame, positions: positions, drawRect: brect, view: v)
            }
        }

        func unexecute() {
            print(" ")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(frameBoxInfo)

    }

    override var representedObject: Any? {
        didSet {
            // Update the view, if already loaded.
        }
    }
}

Я пытался добавить

undoManager?.registerUndo(withTarget: self, selector: #selector(readd), object: frame)

для функции execute в классе DrawShape, но, к сожалению, я получаю следующую ошибку:

Instance member 'undoManager' of type 'NSResponder' cannot be used on instance of nested type 'ViewController.DrawShape'

Ожидаемый / желаемый результат - возможность регистрировать отмену (для отмены и повторного выполнения команды) с использованием undoManager в реализации CommandPattern в swift. Фактический результат заключается в том, что я не могу преодолеть ошибку и могу отменить / повторить что-либо.

...