ios - 在没有 PKCanvasView 的情况下使用 PKToolPicker

标签 ios swift swiftui uiviewrepresentable pencilkit

我正在尝试使用 PKToolPicker来自 PencilKit (iOS/Swift) 来自自定义 View (不是 PKCanvasView)。自定义 View 符合 PKToolPickerObserver .在编译期间一切正常,但我从来没有看到 PKToolPicker!如果我用 PKCanvasView 替换我的自定义 View ,一切正常!
我在 SwiftUI 中使用 UIViewRepresentable 执行此操作(因此 First Responder 似乎是个谜!)。
这是有问题的 SwiftUI View :

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

如果我替换 myViewPKCanvasView上面,将看到 PKToolPicker。
为了完整起见,这里是 MyView stub :
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 是否有一些未记录的要求?

最佳答案

这是在 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()
        }
    }
}

关于ios - 在没有 PKCanvasView 的情况下使用 PKToolPicker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63033787/

相关文章:

iphone - 编辑模式后 UITableViewCell 刷新问题

ios - 无法在 swift 中使用 "floor"

ios - 从 Xcode iOS 项目运行 swift 脚本作为构建阶段

iphone - 第一次使用 swift(不是 objective-c)启动 iPhone 应用程序时,如何播放介绍视频?

SwiftUI 捕获从基于 Web 的登录表单发回的 RedirectUri

ios - 如何在 SwiftUI HStack 中隐藏剪辑 View

ios - 当用户完成我的 iOS 应用程序时,将以前的应用程序带回前台

iphone - awakeFromNib 不是调用而是显示 xib

ios - SceneKit 在 Xcode 6 beta 3 中损坏

animation - 使用 SwiftUI 动画列表中的行更改