在没有PKCanvasView的情况下使用PKToolPicker

时间:2020-07-22 12:04:32

标签: ios swift swiftui uiviewrepresentable pencilkit

我试图从自定义视图(不是PKCanvasView)使用PencilKit(iOS / Swift)中的PKToolPicker。自定义视图符合PKToolPickerObserver。在编译期间一切正常,但是我再也看不到PKToolPicker了!如果我将自定义视图替换为PKCanvasView,则一切正常!

我正在使用UIViewRepresentable在SwiftUI中进行此操作(因此“第一响应者”似乎是个谜!)。

这是有问题的SwiftUI视图:

struct PencilKitView: UIViewRepresentable {
    typealias UIViewType = myView
    
    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) -> myView {
        let canvasView = myView()
        
        canvasView.isOpaque = false
        canvasView.backgroundColor = UIColor.clear
        canvasView.becomeFirstResponder()

        if let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first,
            let toolPicker = PKToolPicker.shared(for: window) {
            toolPicker.addObserver(canvasView)
            toolPicker.addObserver(coordinator)
            toolPicker.setVisible(true, forFirstResponder: canvasView)
        }
        return canvasView
    }
    
    func updateUIView(_ uiView: myView, context: Context) {
        
    }
}

如果我将myView替换为上面的PKCanvasView,将看到PKToolPicker。

为了完整起见,这是MyView存根:

class myView: UIScrollView, PKToolPickerObserver {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    public func toolPickerVisibilityDidChange(_ toolPicker: PKToolPicker) {
        /// some code
    }
    
    public func toolPickerSelectedToolDidChange(_ toolPicker: PKToolPicker) {
        /// some code
    }
    
    public func toolPickerIsRulerActiveDidChange(_ toolPicker: PKToolPicker) {
        /// some code
    }
    
    public func toolPickerFramesObscuredDidChange(_ toolPicker: PKToolPicker) {
        /// some code
    }
}

有人成功做到了吗?采用PKToolPicker是否有一些未记录的要求?

1 个答案:

答案 0 :(得分:1)

这是显示SwiftUI中任何自定义UIView的PKToolPicker的最简单演示。

通过Xcode 11.4 / iOS 13.4测试

demo

struct ToolPickerDemo: View {
    @State private var showPicker = false
    var body: some View {
        Button("Picker") { self.showPicker.toggle() }
            .background(ToolPickerHelper(isActive: $showPicker))
    }
}

class PickerHelperView: UIView {
    override var canBecomeFirstResponder: Bool { true }
}

struct ToolPickerHelper: UIViewRepresentable {
    @Binding var isActive: Bool

    func makeUIView(context: Context) -> PickerHelperView {
        PickerHelperView()
    }

    func updateUIView(_ uiView: PickerHelperView, context: Context) {
        guard let window = uiView.window else { return }

        let picker = PKToolPicker.shared(for: window)
        picker?.setVisible(isActive, forFirstResponder: uiView)

        DispatchQueue.main.async {
            uiView.becomeFirstResponder()
        }
    }
}