SwiftUI签名预览无法显示最后一笔绘制内容的问题求助
签名预览无法实时显示最后一笔绘制内容的解决方案
我在将signatureView.signature存入变量并直接作为图片输出时,遇到了无法显示最后一笔绘制内容的问题——绘制2笔仅显示第1笔,绘制3笔仅显示前2笔,始终无法显示最后一笔。
相关代码
主视图核心代码
@State private var signatureImage: UIImage? @Binding var signature: String SignatureCaptureView(signatureImage: $signatureImage) .frame(height: 200) .border(Color.gray, width: 1) if let img = signatureImage { Image(uiImage: img) .resizable() .scaledToFit() .frame(width: 300, height: 200) .background(Color.gray.opacity(0.2)) .id(UUID()) } else { Text("Noch keine Unterschrift") .background(Color.gray.opacity(0.2)) .frame(width: 300, height: 200) }
SignatureCaptureView.swift代码
import SwiftUI import SwiftSignatureView struct SignatureCaptureView: UIViewRepresentable { @Binding var signatureImage: UIImage? private var signatureView: SwiftSignatureView // 未使用的冗余属性 var coordinator: Coordinator? // 未使用的冗余属性 func getCroppedSignature(from view: SwiftSignatureView) -> UIImage? { return view.getCroppedSignature() } init(signatureImage: Binding<UIImage?>) { self._signatureImage = signatureImage self.signatureView = SwiftSignatureView() } func makeUIView(context: Context) -> SwiftSignatureView { let signatureView = SwiftSignatureView() signatureView.delegate = context.coordinator return signatureView } func updateUIView(_ uiView: SwiftSignatureView, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, SwiftSignatureViewDelegate { var parent: SignatureCaptureView var signatureView: PencilKitSignatureView? // 未正确使用的属性 init(_ parent: SignatureCaptureView) { self.parent = parent } func updateUIView(_ view: ISignatureView) { if let signatureView = view as? PencilKitSignatureView { parent.signatureImage = signatureView.signature view.signature = signatureView.signature } } func swiftSignatureViewDidDrawGesture(_ view: ISignatureView, _ tap: UIGestureRecognizer) { if let signatureView = view as? PencilKitSignatureView { // 未启用的更新逻辑 } } func swiftSignatureViewDidDraw(_ view: ISignatureView) { print("triggered: DidDraw") if let signatureView = view as? PencilKitSignatureView { print("saving...") parent.signatureImage = signatureView.signature } else { print("View konnte nicht zu PencilKitSignatureView gecastet werden") } } } }
完整SignatureView代码
import SwiftUI import SwiftSignatureView struct SignatureView: View { @State private var signatureImage: UIImage? @Binding var signature: String var body: some View { VStack(spacing: 20) { Text("Bitte unterschreiben:") .font(.headline) SignatureCaptureView(signatureImage: $signatureImage) .frame(height: 200) .border(Color.gray, width: 1) } VStack { HStack(spacing: 20) { Button("Speichern") { if let img = signatureImage { if let data = img.pngData() { signature = data.base64EncodedString() } else { print("Fehler bei der Datenkonvertierung") } } else { print("Kein Bild vorhanden") } } Button("Zurücksetzen") { signatureImage = nil // 未重置签名绘制视图 } } // 签名预览区域 ZStack { if let img = signatureImage { Image(uiImage: img) .resizable() .scaledToFit() .frame(width: 300, height: 200) .background(Color.gray.opacity(0.2)) .id(UUID()) } else { Text("Noch keine Unterschrift") .background(Color.gray.opacity(0.2)) .frame(width: 300, height: 200) } } } .padding() } }
问题表现截图
- 绘制2笔时的预览效果:

- 绘制第3笔(1和2之间的线条)时,预览仍不显示该笔:

修复方案
问题根源
swiftSignatureViewDidDraw回调触发时,signatureView.signature可能尚未完成最新绘制内容的渲染- 代码中存在未使用的冗余属性,导致逻辑混乱
- 预览视图中
.id(UUID())强制重建视图,干扰了状态驱动的更新逻辑
修复步骤
- 移除冗余属性:删除
SignatureCaptureView中未使用的signatureView和coordinator属性 - 修正图像获取逻辑:使用
getCroppedSignature()方法替代直接读取signature,确保获取完整渲染的签名图像 - 主线程更新状态:SwiftUI状态更新必须在主线程执行,添加
DispatchQueue.main.async调度 - 优化预览视图:移除
.id(UUID()),让状态变化自然驱动视图更新
修复后的SignatureCaptureView代码
import SwiftUI import SwiftSignatureView struct SignatureCaptureView: UIViewRepresentable { @Binding var signatureImage: UIImage? private var signatureView: SwiftSignatureView? // 保存视图引用用于重置 func getCroppedSignature(from view: SwiftSignatureView) -> UIImage? { return view.getCroppedSignature() } init(signatureImage: Binding<UIImage?>) { self._signatureImage = signatureImage } func makeUIView(context: Context) -> SwiftSignatureView { let view = SwiftSignatureView() view.delegate = context.coordinator self.signatureView = view return view } func updateUIView(_ uiView: SwiftSignatureView, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(self) } // 添加重置签名方法 func resetSignature() { signatureView?.clear() signatureImage = nil } class Coordinator: NSObject, SwiftSignatureViewDelegate { var parent: SignatureCaptureView init(_ parent: SignatureCaptureView) { self.parent = parent } func swiftSignatureViewDidDraw(_ view: ISignatureView) { guard let signatureView = view as? SwiftSignatureView else { print("View konnte nicht zu SwiftSignatureView gecastet werden") return } DispatchQueue.main.async { self.parent.signatureImage = signatureView.getCroppedSignature() } } } }
修复后的预览视图代码(SignatureView中ZStack部分)
ZStack { if let img = signatureImage { Image(uiImage: img) .resizable() .scaledToFit() .frame(width: 300, height: 200) .background(Color.gray.opacity(0.2)) } else { Text("Noch keine Unterschrift") .background(Color.gray.opacity(0.2)) .frame(width: 300, height: 200) } }
完善重置功能
修改SignatureView中的"Zurücksetzen"按钮,添加签名视图重置逻辑:
// 先给SignatureCaptureView添加@StateObject或使用PreferenceKey获取引用,这里简化使用@Binding传递重置信号 // 例如在SignatureView中添加: @State private var shouldReset = false // 然后修改SignatureCaptureView调用reset方法 SignatureCaptureView(signatureImage: $signatureImage) .frame(height: 200) .border(Color.gray, width: 1) .onChange(of: shouldReset) { newValue in if newValue { // 获取视图引用并调用resetSignature(),可通过PreferenceKey实现 shouldReset = false } } // 按钮修改为: Button("Zurücksetzen") { shouldReset = true }
内容的提问来源于stack exchange,提问作者Arakel
相关产品推荐
相关产品推荐

