简体   繁体   中英

How to use PKToolPicker with PKCanvasView in SwiftUI

Currently, I am able to have a separate PKCanvasView and a PKToolPicker that is shown when a button is tapped on. However, the tool is not being transferred between the picker and the canvas view. Does anyone have any idea how to link the two such that when I change the tool in the picker, the tool is updated in the canvas view as well? I've attached my code below. Thank you!

import SwiftUI
import PencilKit

struct DrawingView: View {
    @State private var showPicker = false
    @State private var canvasView = PKCanvasView()
    var body: some View {
        VStack {
            PencilKitView(isActive: $showPicker, canvasView: $canvasView)
            Button("Picker") { self.showPicker.toggle() }
        }
    }
}

struct PencilKitView: UIViewRepresentable {
    typealias UIViewType = PKCanvasView
    @Binding var isActive: Bool
    @Binding var canvasView: PKCanvasView

    let coordinator = Coordinator()
    
    class Coordinator: NSObject, PKToolPickerObserver {
        
        func toolPickerSelectedToolDidChange(_ toolPicker: PKToolPicker) {
            // some code
        }
        func toolPickerVisibilityDidChange(_ toolPicker: PKToolPicker) {
            // some code
        }
        
    }
    
    func makeCoordinator() -> PencilKitView.Coordinator {
        return Coordinator()
    }
    
    func makeUIView(context: Context) -> PKCanvasView {
        canvasView
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {
        uiView.isOpaque = true
        uiView.becomeFirstResponder()

        let toolPicker = PKToolPicker.init()
        toolPicker.addObserver(uiView)
        toolPicker.addObserver(coordinator)
        toolPicker.setVisible(isActive, forFirstResponder: uiView)
        
        DispatchQueue.main.async {
            uiView.becomeFirstResponder()
        }
    }
}

Solved it!

import SwiftUI
import PencilKit

struct DrawingView: View {
    private var canvasView = PKCanvasView()

    var body: some View {
        MyCanvas(canvasView: canvasView)
    }
}

struct MyCanvas: UIViewRepresentable {
    var canvasView: PKCanvasView
    let picker = PKToolPicker.init()
    
    func makeUIView(context: Context) -> PKCanvasView {
        self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
        self.canvasView.becomeFirstResponder()
        return canvasView
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {
        picker.addObserver(canvasView)
        picker.setVisible(true, forFirstResponder: uiView)
        DispatchQueue.main.async {
            uiView.becomeFirstResponder()
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM