gpt4 book ai didi

swiftui - 使用 SwiftUI 实现 PencilKit 撤消功能

转载 作者:行者123 更新时间:2023-12-05 08:39:14 25 4
gpt4 key购买 nike

编辑:感谢一些反馈,我已经能够部分工作(更新代码以反射(reflect)当前更改)。

即使该应用程序似乎按预期运行,我仍然收到“正在修改状态...”警告。如何在 updateUIView 中更新 View 的绘图并使用 canvasViewDrawingDidChange 将新绘图推送到堆栈上而不导致此问题?我曾尝试将其包装在调度调用中,但这只会造成无限循环。


我正在尝试在 UIViewRepresentable (PKCanvasView) 中实现撤消功能。我有一个名为 WriterView 的父 SwiftUI View ,它包含两个按钮和 Canvas 。

这是父 View :

struct WriterView: View {
@State var drawings: [PKDrawing] = [PKDrawing()]

var body: some View {
VStack(spacing: 10) {
Button("Clear") {
self.drawings = []
}
Button("Undo") {
if !self.drawings.isEmpty {
self.drawings.removeLast()
}
}
MyCanvas(drawings: $drawings)
}
}
}

下面是我如何实现我的 UIViewRepresentable:

struct MyCanvas: UIViewRepresentable {
@Binding var drawings: [PKDrawing]

func makeUIView(context: Context) -> PKCanvasView {
let canvas = PKCanvasView()
canvas.delegate = context.coordinator
return canvas
}

func updateUIView(_ uiView: PKCanvasView, context: Context) {
uiView.drawing = self.drawings.last ?? PKDrawing()
}

func makeCoordinator() -> Coordinator {
Coordinator(self._drawings)
}

class Coordinator: NSObject, PKCanvasViewDelegate {
@Binding drawings: [PKDrawing]

init(_ drawings: Binding<[PKDrawing]>) {
self._drawings = drawings
}

func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
drawings.append(canvasView.drawing)
}
}
}

我收到以下错误:

[SwiftUI] Modifying state during view update, this will cause undefined behavior.

大概是我的协调员的 did change 函数引起的,但我不确定如何解决这个问题。解决这个问题的最佳方法是什么?

谢谢!

最佳答案

我终于(无意中)弄清楚了如何使用 UndoManager 来做到这一点。我仍然不确定 为什么 这行得通,因为我从来不需要调用 self.undoManager?.registerUndo()。如果您理解为什么我从来不需要注册事件,请发表评论。

这是我的工作父 View :

struct Writer: View {
@Environment(\.undoManager) private var undoManager
@State private var canvasView = PKCanvasView()

var body: some View {
VStack(spacing: 10) {
Button("Clear") {
canvasView.drawing = PKDrawing()
}
Button("Undo") {
undoManager?.undo()
}
Button("Redo") {
undoManager?.redo()
}
MyCanvas(canvasView: $canvasView)
}
}
}

这是我工作的 subview :

struct MyCanvas: UIViewRepresentable {
@Binding var canvasView: PKCanvasView

func makeUIView(context: Context) -> PKCanvasView {
canvasView.drawingPolicy = .anyInput
canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
return canvasView
}

func updateUIView(_ canvasView: PKCanvasView, context: Context) { }
}

这当然感觉更像是 SwiftUI 的预期方法,并且肯定比我之前所做的尝试更优雅。

关于swiftui - 使用 SwiftUI 实现 PencilKit 撤消功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60592875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com