Home > Net >  Disable button if PKCanvasView is empty
Disable button if PKCanvasView is empty

Time:01-26

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
  •  Tags:  
  • Related