如何在 SwiftUI 中使 PKCanvasView 可缩放?

问题描述 投票:0回答:2

有一个像这样的 PKCanvasView 设置:

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


extension CanvasView: UIViewRepresentable {
  func makeUIView(context: Context) -> PKCanvasView {
      canvasView.tool = PKInkingTool(.pencil, color: .gray, width: 20)
//    #if targetEnvironment(simulator)
      canvasView.drawingPolicy = .anyInput
//    #endif
    canvasView.delegate = context.coordinator
    showToolPicker()
    return canvasView
  }

  func updateUIView(_ uiView: PKCanvasView, context: Context) {}

  func makeCoordinator() -> Coordinator {
    Coordinator(canvasView: $canvasView, onSaved: onSaved)
  }
}

然后我在 SwiftUI 中使用它,如下所示:

        VStack {
            Spacer()
            CanvasView(canvasView: $canvasView, onSaved: saveDrawing)
                .aspectRatio(1.0, contentMode: .fit)
            Spacer()
        }

但第二次我把它放在 ScrollView 中以添加平移和缩放功能,如下所示

ScrollView {    //prevents drawing with finger
        VStack {
            Spacer()
            CanvasView(canvasView: $canvasView, onSaved: saveDrawing)
                .aspectRatio(1.0, contentMode: .fit)
            Spacer()
        }
}

它不再允许我用手指绘图,假设它正在尝试滚动。我正在寻找像苹果的自由格式应用程序那样的行为。用手指进行绘制,捏合进行缩放,2 根手指进行平移。

swift swiftui uiscrollview scrollview pencilkit
2个回答
3
投票

已更新

经过一番澄清后,我添加了将整个绘图区域缩小到小于屏幕尺寸的功能。

Pencil Kit 的画布非常坚固,具有内置缩放和平移功能。因此无需添加滚动视图或平移手势,只需设置画布内容的大小、缩放比例和插图即可。

对于滚动和平移,为绘图区域设置较大的画布内容大小:

canvasView.contentSize = CGSize(width: 1500, height: 1000)

要进行缩放,请设置所需的缩放比例:

canvasView.minimumZoomScale = 0.2
canvasView.maximumZoomScale = 4.0

为了允许整个绘图区域缩小到小于滚动视图的框架大小,请添加内容插图:

canvasView.contentInset = UIEdgeInsets(top: 500, left: 500, bottom: 500, right: 500)

以下是带有工具选择器的基本 SwiftUI 铅笔应用程序。它具有捏合缩放、两指平移和手指绘制功能:

import SwiftUI
import PencilKit

struct ContentView: View {
    var body: some View {
        CanvasView()
    }
}

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

extension CanvasView: UIViewRepresentable {
    func makeUIView(context: Context) -> PKCanvasView {
            // canvas
        canvasView.contentSize = CGSize(width: 1500, height: 1000)
        canvasView.drawingPolicy = .anyInput
        canvasView.minimumZoomScale = 0.2
        canvasView.maximumZoomScale = 4.0
        canvasView.backgroundColor = UIColor(red: 0.9, green: 0.9, blue: 0.9, alpha: 1.0)
        canvasView.contentInset = UIEdgeInsets(top: 500, left: 500, bottom: 500, right: 500)
        canvasView.becomeFirstResponder()
        
            //toolpicker
        toolPicker.setVisible(true, forFirstResponder: canvasView)
        toolPicker.addObserver(canvasView)
        
        return canvasView
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {}
}

注意:下面的 gif 是在 iPad 上使用上面的代码创建的,工具选择器移到了一侧。背景颜色(白色)是使用工具选择器的标记手动绘制在绘图区域上的,以更好地演示缩放和平移。独立于绘图区域设置 scollview 的背景颜色是一项需要的增强功能。

生成的应用程序如下所示:

enter image description here


0
投票

如果您仍然遇到这个问题,这将解决背景问题

var body: some View {
        ZStack {
            Color.red
            
            CanvasView(canvasView: $canvasView)
                .ignoresSafeArea()
            
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.