【问题标题】:How to toggle a PKCanvasView's editability如何切换 PKCanvasView 可编辑性
【发布时间】:2021-04-22 23:52:07
【问题描述】:

我正在使用 PencilKit 允许用户在自定义画布上绘图,并且在各种功能中,我希望允许用户决定画布是否可编辑。如果它是可编辑的,那么绘图工具是可见的并且画布接受手指和铅笔手势,否则它只接受来自铅笔的手势并且手指手势用于其他事情。

这是我创建的画布视图:

struct CanvasView {
    @Binding var canvasView: PKCanvasView
    @State var toolPicker: PKToolPicker = PKToolPicker()
    @Binding var editable: Bool
}

// MARK: - UIViewRepresentable
extension CanvasView: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        canvasView.tool = PKInkingTool(.pen, color: .gray, width: 10)
        canvasView.backgroundColor = .clear
        canvasView.isOpaque = false
        
        canvasView.drawingPolicy = editable ? .anyInput : .pencilOnly
        canvasView.isUserInteractionEnabled = editable
        
        toolPicker.setVisible(editable, forFirstResponder: canvasView)
        toolPicker.addObserver(canvasView)
        canvasView.becomeFirstResponder()
        
        return canvasView
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {}
}

这是我的内容视图:

struct ContentView: View {
    @State private var canvasView = PKCanvasView()
    @State private var isDrawing = true
    ...

    var body: some View {
        NavigationView {
            ZStack {
                ...
                
                CanvasView(canvasView: $canvasView, editable: self.$isDrawing)
                    .allowsHitTesting(false)
                    .navigationBarTitle(Text("Drawing Demo"), displayMode: .inline)
                    .navigationBarItems(leading: HStack{}, trailing: HStack {
                        
                        ...
                        
                        Button(action: toggleIsDrawing) {
                            Image(systemName: "pencil.tip.crop.circle")
                        }
                    })
            }
        }.navigationViewStyle(StackNavigationViewStyle())
    }
}

...

// MARK: - Actions
private extension ContentView {
    ...
    
    func toggleIsDrawing() {
        self.isDrawing = !self.isDrawing
    }

简而言之:为了切换我的画布视图的可编辑性,我有一个 @State var (isDrawing),每次用户点击导航栏中的铅笔图标。这与具有画布视图的可编辑属性的 @Binding 属性绑定。但问题是没有什么会再次触发我的画布视图的 makeUIView(context:) 方法,因此实际上没有任何变化。我期待对我的 @State 变量 (isDrawing) 进行更改以导致重新绘制整个视图层次结构,从而重新计算每个属性,以及 makeUIView( ) 方法被召回,但显然情况并非如此。你将如何解决这个问题?

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    updateUIView 函数用于该场景——它允许您在 @State 或属性更改时修改视图。

    另外,您可能想要删除 .allowsHitTesting(false),因为它似乎会使 PencilKit 视图无法使用。

    extension CanvasView: UIViewRepresentable {
        func makeUIView(context: Context) -> some UIView {
            canvasView.tool = PKInkingTool(.pen, color: .gray, width: 10)
            canvasView.backgroundColor = .clear
            canvasView.isOpaque = false
            canvasView.becomeFirstResponder()
            
            return canvasView
        }
        
        func updateUIView(_ uiView: UIViewType, context: Context) {
            canvasView.drawingPolicy = editable ? .anyInput : .pencilOnly
            canvasView.isUserInteractionEnabled = editable
            
            toolPicker.setVisible(editable, forFirstResponder: canvasView)
            toolPicker.addObserver(canvasView)
        }
    }
    
    CanvasView(canvasView: $canvasView, editable: self.$isDrawing)
      //.allowsHitTesting(false) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      • 2018-01-03
      • 2011-09-26
      • 1970-01-01
      • 2016-09-05
      相关资源
      最近更新 更多