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?
Lasso no longer works with iOS17
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?
iOS 17.1 appears to me to have resolved this issue.