【问题标题】:Using PKToolPicker without PKCanvasView在没有 PKCanvasView 的情况下使用 PKToolPicker
【发布时间】:2020-07-22 12:04:32
【问题描述】:

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

我在 SwiftUI 中使用 UIViewRepresentable 执行此操作(因此 First Responder 似乎是个谜!)。

这是有问题的 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) {
        
    }
}

如果我用上面的PKCanvasView 替换myView,就会看到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 是否有一些未记录的要求?

【问题讨论】:

    标签: ios swift swiftui uiviewrepresentable pencilkit


    【解决方案1】:

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

    使用 Xcode 11.4 / iOS 13.4 测试

    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()
            }
        }
    }
    

    【讨论】:

    • 这很快,而且效果很好!自定义 uiview 中缺少对 canBecomeFirstResponder 的覆盖。
    猜你喜欢
    • 2023-01-24
    • 1970-01-01
    • 2021-10-30
    • 2010-12-09
    • 2018-03-02
    • 2019-06-20
    • 2014-10-07
    • 2018-04-08
    • 2011-10-26
    相关资源
    最近更新 更多