You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift开发:如何在PencilKit中加载可缩放平移的背景编辑图?

PKCanvasView背景图适配与手势交互问题

我是Swift及移动开发新手,正在开发一款适用于macOS和iPad的简易应用,目标是显示一张图片并允许用户在其上书写。目前已实现基础功能,但存在问题:加载的背景图超出可视屏幕。我希望实现以下效果:

  • 默认将图片缩放至适配可视屏幕;
  • 支持标准捏合手势缩放、双指手势平移;
  • 可在整张图片上进行书写操作。

我已搜索并尝试了一些方法,但仍未理清各组件的协作逻辑,希望得到帮助或指导。

当前代码

import SwiftUI
import SwiftData
import PencilKit

struct ContentView: View {
    @Environment(\.undoManager) private var undoManager
    @State private var canvasView = PKCanvasView()

    var body: some View {
        
        VStack{
            HStack(spacing: 5) {
                Spacer(minLength: 1)
                Button("Clear") {
                    canvasView.drawing = PKDrawing()
                }.buttonStyle(.borderedProminent)
                Spacer(minLength: 1)
                Button("Undo") {
                    undoManager?.undo()
                }.buttonStyle(.borderedProminent)
                Spacer(minLength: 1)
                Button("Redo") {
                    undoManager?.redo()
                }.buttonStyle(.borderedProminent)
                Spacer(minLength: 1)
                Button("Remove Object") {
                    self.canvasView.tool = PKEraserTool(.vector);
                }.buttonStyle(.borderedProminent)
                Spacer(minLength: 1)
                Button("Erase") {
                    self.canvasView.tool = PKEraserTool(.bitmap, width: 3);
                }.buttonStyle(.borderedProminent)
                Button("Draw") {
                    let color = PKInkingTool.convertColor(.black, from: .dark, to: .light)
                    self.canvasView.tool = PKInkingTool(.monoline, color: color, width: 3)
                }.buttonStyle(.borderedProminent)
                Spacer(minLength: 1)
            }
            
            GeometryReader { proxy in
                VStack {MyCanvas(canvasView: $canvasView)}
                    .frame(width: proxy.size.width, height: proxy.size.height)
                    .background(.black)
            }
        }
    }

}

struct MyCanvas: UIViewRepresentable {
    @Binding var canvasView: PKCanvasView
    //let picker = PKToolPicker()
    let screenSize: CGRect = UIScreen.main.bounds

    func makeUIView(context: Context) -> PKCanvasView {

        //canvasView.contentSize = CGSize(width: 1500, height: 1000)
        canvasView.contentInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        canvasView.minimumZoomScale = 0.2
        canvasView.maximumZoomScale = 4.0
        canvasView.drawingPolicy = .anyInput
        canvasView.isOpaque = false
        canvasView.backgroundColor = UIColor.clear
        canvasView.frame(forAlignmentRect: screenSize)
        canvasView.becomeFirstResponder()

        let imageView = UIImageView(image: UIImage(named: "tracker"))
        imageView.frame(forAlignmentRect: screenSize)
        imageView.contentMode =  UIView.ContentMode.scaleAspectFit

        let contentView = canvasView.subviews[0]
        contentView.addSubview(imageView)
        contentView.sendSubviewToBack(imageView)

        //picker.addObserver(canvasView)
        //picker.setVisible(true, forFirstResponder: canvasView)

        let color = PKInkingTool.convertColor(.black, from: .dark, to: .light)
        canvasView.tool = PKInkingTool(.monoline, color: color, width: 3)
        return canvasView
    }

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

#Preview {
    ContentView()
        .modelContainer(for: Item.self, inMemory: true)
}

struct Landscape_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewInterfaceOrientation(.landscapeLeft)
    }
}

当前效果

iOS应用界面截图


内容的提问来源于stack exchange,提问作者spkane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:25:57