사용자가 손가락 제스처 또는 연필로 문서에 "그리기"할 수있는 주석 도구가 포함 된 프로젝트 작업 중입니다. 당연히, 나는 그려진 경로에 대해 실행 취소/다시 실행을 구현하는 데 열중하고 있습니다.드로잉 응용 프로그램에서 UndoManager를 사용하여 다시 실행 구현 Swift 3
드로잉 앱에 대한 구현은 비교적 일반적입니다. 사용자가 화면에서 보는 것은 캐싱 된 비트 맵 이미지 (현재 경로보다 먼저 그려진 모든 경로의 스냅 샷)와 현재 경로의 "라이브"렌더링 (UIBezierPath)의 조합입니다. touchesEnded가 트리거되면 새 경로가 비트 맵에 추가됩니다.
나는 비교적 적은 문제만으로 실행 취소를 구현할 수있었습니다. 나는 클래스의 표준를 UndoManager를 만들었습니다
let myUndoManager : UndoManager = {
let mUM : UndoManager = UndoManager()
mUM.levelsOfUndo = 6
return mUM
}()
새로운 캐시 경로를 렌더링하는 touchesEnded의 끝에서 호출되는 함수가 drawBitmap이라고합니다. 이 함수의 시작에서, 가정 이전 캐시 경로가 새로운 하나를 그리기 전에, 내가 실행 취소 관리자와 다음 실행 취소 작업 등록 :
let previousCachedPath : UIImage = self.cachedPath
self.myUndoManager.registerUndo(withTarget: self, selector: #selector(self.setBitmap(_:)), object: previousCachedPath)
setBitmap을 (_ previousCachedPath :있는 UIImage)는 기능입니다 표시된 비트 맵을 제공된 이미지로 재설정합니다.
각각 undo() 및 redo() 메소드에 연결된 실행 취소/다시 실행 버튼이 있습니다. 이 버튼이 활성화되어야 할 때를 명령하는 로직을 제외하고 (즉, 아무 것도 그리지 않았을 때 실행 취소를 누르지 못하도록하기 위해) 이들은 단순히 myUndoManager.undo() 및 myUndoManager.redo()를 호출합니다.
func undo() -> Void {
guard self.myUndoManager.canUndo else { return }
self.myUndoManager.undo()
if !self.redoButton.isEnabled {
self.redoButton.isEnabled = true
}
if !self.myUndoManager.canUndo {
self.undoButton.isEnabled = false
}
self.setNeedsDisplay()
}
func redo() -> Void {
guard self.myUndoManager.canRedo else { return }
self.myUndoManager.redo()
if !self.undoButton.isEnabled {
self.undoButton.isEnabled = true
}
if !self.myUndoManager.canRedo {
self.redoButton.isEnabled = false
}
self.setNeedsDisplay()
}
앞서 언급했듯이 실행 취소는 지정된 6 단계 실행 취소 가능성에 완벽하게 작동합니다. 그러나, 나는 분명히 redo로 무언가를 놓치고있다. 내 첫 번째 희망은 undoManager가 undo가 호출 될 때 undo 작업을 undo 스택에서 redo 스택으로 자동 전송한다는 것이었지만, 이것은 분명히 일어나지 않았다.
나는 이미 답을 검색 한, 그리고 내가 따라 상호 재귀를 사용할 수 있습니다 필요에 가장 가까운 생각 :
Using NSUndoManager, how to register undos using Swift closures
는 그러나, 나는이 일을 할 수 없었습니다. 따라서 어떤 도움을 주셔서 감사합니다!
트릭은 _one_ 메소드 만 있어야하며 실행 취소와 다시 실행 모두 호출해야한다는 것입니다. 다시 실행 취소는 실행 취소입니다. 실행 취소의 실행 취소는 다시 실행입니다. 그것은 내 책의 장을 읽는 것을 도울 것입니다 : http://www.apeth.com/iOSBook/ch39.html – matt
감사합니다 - 나는 오늘 아침에 책을 읽게 될 것이고 여러분이 어떻게 시작하는지 알려줄 것입니다! – Sparky
@matt 고마워요. 완벽하게 작동했습니다. 당신이 제안했듯이 모든 것을 하나의 메서드로 결합했습니다.이 경우에는 setBitmap (_ :)입니다. 내가 설명한 방법 중 하나를 사용하여 작업 할 수있게되었습니다. 나는 다른 사람들을 돕기 위해 내 솔루션을 게시했습니다. – Sparky