Lasso no longer works with iOS17

Since updating to iOS17, lasso no longer works in Pencilkit with SwiftUI support using UIViewRepresentable. It works in PKToolPicker, but the programmatically created PKLassoTool does not work. How can I get lasso to work?

This is the simplest reproduction code; Lasso works in 16.4, but not in 17.

import SwiftUI
import PencilKit

struct ContentView: View {
    @State var canvas = CanvasTest()
    
    var body: some View {
        VStack {
            canvas
            Text("Pen")
                .onTapGesture {
                    canvas.canvasView.tool = PKInkingTool(ink: PKInk(.pen), width: 4)
                }
            Text("Lasso")
                .onTapGesture {
                    canvas.canvasView.tool = PKLassoTool()
                }
        }
        .padding()
    }
}

struct CanvasTest: UIViewRepresentable {
    let canvasView = PKCanvasView()
    func makeUIView(context: Context) -> some PKCanvasView {
        canvasView.drawingPolicy = .anyInput
        canvasView.tool = PKInkingTool(ink: PKInk(.pen), width: 20)
        canvasView.delegate = context.coordinator
        return canvasView
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
}

extension CanvasTest {
    final class Coordinator: NSObject, PKCanvasViewDelegate {
        var parent: CanvasTest

        init(_ uiView: CanvasTest) {
            self.parent = uiView
        }
    }
    func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
        canvasView.tool = PKLassoTool()
    }
}

Sorry, this one is even simpler.

import SwiftUI
import PencilKit

struct ContentView: View {
    @State var canvas = CanvasTest()
    
    var body: some View {
        VStack {
            canvas
            Text("Pen")
                .onTapGesture {
                    canvas.canvasView.tool = PKInkingTool(ink: PKInk(.pen), width: 4)
                }
            Text("Lasso")
                .onTapGesture {
                    canvas.canvasView.tool = PKLassoTool()
                }
        }
        .padding()
    }
}

struct CanvasTest: UIViewRepresentable {
    let canvasView = PKCanvasView()
    func makeUIView(context: Context) -> some PKCanvasView {
        canvasView.drawingPolicy = .anyInput
        canvasView.tool = PKInkingTool(ink: PKInk(.pen), width: 20)
        return canvasView
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
    }

}

Our service is also experiencing the same problem. Is there still no solution?

My solution is a bit hacky. I added the built-in tool PKToolPicker and displayed the tools. When selecting Text("Lasso"), I set self.toolPicker.setVisible(true, forFirstResponder: context.coordinator) so that PKLassoTool can be used. When selecting other tools, I set self.toolPicker.setVisible(false, forFirstResponder: context.coordinator).

It's quite cumbersome, and I hope there is a better way.

let toolPicker = PKToolPicker()

func makeCoordinator() -> Coordinator {

    Coordinator()
    
}

class Coordinator: NSObject, PKToolPickerObserver {

....

}

Just to add that this is also affecting my UIKit app too. Any update yet?

Accepted Answer

iOS 17.1 appears to me to have resolved this issue.

Lasso no longer works with iOS17
 
 
Q