如何防止 List 干扰 PKCanvassView?

时间:2021-06-17 16:43:53

标签: swiftui uigesturerecognizer

寻找有关如何防止 swiftui 列表干扰 PKCanvassView 的建议。这个想法是,当用户在 PCCanvass 视图中绘制时,触摸不会传递到超级视图。

enter image description here

我尝试制作一个视图来阻止触摸被传递到自己工作的超级视图,但是当签名视图放在 ZStack 中时它不起作用。浅灰色背景是 BlockingView 并且它似乎确实在做它应该做的事情。其边界内的触摸不会传递到 List

enter image description here

import UIKit
import SwiftUI

final class BlockingView: UIView, UIGestureRecognizerDelegate
{
    init() {
        super.init(frame: CGRect.zero)
        self.addGestureRecognizer(UIGestureRecognizer())
        self.backgroundColor = .gray2
    }
    required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }

    @objc override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        print("gestureRecognizerShouldBegin")
        return false
    }
}

struct BlockGestureUi: UIViewRepresentable
{
    func makeUIView(context: Context) -> BlockingView {
        return BlockingView()
    }
    
    func updateUIView(_ uiView: BlockingView, context: Context) {}
}

这是嵌入在 swiftUi 列表中的 swiftUi 视图。

import SwiftUI
import PencilKit

struct SignatureUi: View
{
    @State var sigImg: Image?
    @State private var canvasView: PKCanvasView
    
    init() {
        let c = PKCanvasView()
        c.drawingPolicy = .anyInput
    }
    
    var body: some View {
        ZStack(alignment: .bottomLeading) {
            BlockGestureUi()
            ZStack(alignment: .bottomTrailing) {
                CanvasView(canvasView: $canvasView, onSaved: saveDrawing)
                    .border(Color.purple2)
                deleteDrawingBtn.padding(6)
            }
            Avnr14Text(text: "Signature", clr: .purple1).padding(6)
        }
    }
    
    var deleteDrawingBtn: some View {
        Button(action: deleteDrawing) {
            Image(systemName: "trash")
                .renderingMode(.template)
                .foregroundColor(Color.purple1)
        }
    }
}

魔法发生在 CanvassView

import SwiftUI
import PencilKit

struct CanvasView
{
    @Binding var canvasView: PKCanvasView
    let onSaved: () -> Void
    @State var toolPicker = PKToolPicker()
}

// MARK: - UIViewRepresentable
extension CanvasView: UIViewRepresentable {
    func makeUIView(context: Context) -> PKCanvasView {
        canvasView.tool = PKInkingTool(.pen, color: .purple1, width: 10)
        #if targetEnvironment(simulator)
        canvasView.drawingPolicy = .anyInput
        #endif
        canvasView.delegate = context.coordinator
        //canvasView.canCancelContentTouches = true
        //showToolPicker()
        return canvasView
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(canvasView: $canvasView, onSaved: onSaved)
    }
}


// MARK: - Private Methods
private extension CanvasView {
    func showToolPicker() {
        toolPicker.setVisible(true, forFirstResponder: canvasView)
        toolPicker.addObserver(canvasView)
        canvasView.becomeFirstResponder()
    }
}

// MARK: - Coordinator
class Coordinator: NSObject {
    var canvasView: Binding<PKCanvasView>
    let onSaved: () -> Void
    
    // MARK: - Initializers
    init(canvasView: Binding<PKCanvasView>, onSaved: @escaping () -> Void) {
        self.canvasView = canvasView
        self.onSaved = onSaved
    }
}

// MARK: - PKCanvasViewDelegate
extension Coordinator: PKCanvasViewDelegate {
    func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
        if !canvasView.drawing.bounds.isEmpty {
            onSaved()
        }
    }
}

0 个答案:

没有答案