I'm building a format using SwiftUI on which a user has to draw a signature, and must not be allowed to move forward if the PKCanvasView is empty. I'm trying to disable the next button by using: .disabled(pkCanvasView.drawing.bounds.isEmpty)but this condition always return true so the button is always disable. But if I try the following, it seems the condition is working.
Button(text: "SAVE") {
if pkCanvasView.drawing.bounds.isEmpty {
showAlert = true //CONDITION WORKS
} else {
//Do something else
}
}
So this way an alert shows if the canvas is empty, but in this case I cannot use an alert, the button has to be disable. Any ideas on how I can achive this by using the .disabled()property?
EDIT:
This is how I wrapped PKCanvasView in a UIViewRepresentable
struct SignatureCanvas: UIViewRepresentable {
@Binding var canvas: PKCanvasView
func makeUIView(context: Context) -> PKCanvasView {
canvas.drawingPolicy = .anyInput
canvas.tool = PKInkingTool(.pen, color: .black, width: 10)
return canvas
}
func updateUIView(_ canvasView: PKCanvasView, context: Context) { }
func checkIfEmpty() -> Bool {
if canvas.drawing.strokes.isEmpty {
return true
} else {
return false
}
}
}
CodePudding user response:
You need to implement the coordinator pattern with a PKCanvasView delegate.
struct SignatureCanvas: UIViewRepresentable {
@Binding var canvas: PKCanvasView
@Binding var flag: Bool
//Create the coordinator and assign it to the context
func makeCoordinator() -> Coordinator {
Coordinator(flag: $flag)
}
func makeUIView(context: Context) -> PKCanvasView {
canvas.drawingPolicy = .anyInput
canvas.tool = PKInkingTool(.pen, color: .black, width: 10)
//assign coordinator as delegate
canvas.delegate = context.coordinator
return canvas
}
func updateUIView(_ canvasView: PKCanvasView, context: Context) {}
func checkIfEmpty() -> Bool {
if canvas.drawing.strokes.isEmpty {
return true
} else {
return false
}
}
}
// the coordinator storing the binding and implementing the delegate
class Coordinator: NSObject {
@Binding var flag: Bool
init(flag: Binding<Bool>) {
self._flag = flag
}
}
extension Coordinator: PKCanvasViewDelegate {
//gets called when the drawing changes
func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
//update the binding
flag = canvasView.drawing.strokes.isEmpty
}
}
In your ContentView
VStack {
SignatureCanvas(canvas: $canvas, flag: $flag)
Button(text: "SAVE") {
}
.disabled(flag)
}
And of course you need the appropriate state variable in Contentview
@State private var flag: Bool = true
