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

SwiftUI集成PKCanvasView出现屏幕闪烁及IOSurface分配失败问题

解决PKCanvasView在SwiftUI中IOSurface分配失败与屏幕闪烁问题

问题根源

你当前的实现直接将ViewModel中的PKCanvasView实例通过Binding传递给UIViewRepresentable,这违背了SwiftUI对UIViewRepresentable的生命周期管理规则——UIViewRepresentable应当自行创建和管理UIView实例,复用外部传入的实例会导致渲染资源(如IOSurface)分配冲突,进而引发日志报错和屏幕闪烁。

解决方案

1. 重构UIViewRepresentable,自行创建PKCanvasView

修改DrawingCanvasView,让它负责创建画布实例,并通过回调将实例传递给外部:

struct DrawingCanvasView: UIViewRepresentable {
    let drawingPolicy: PKCanvasViewDrawingPolicy
    let onCanvasCreated: (PKCanvasView) -> Void

    func makeUIView(context: Context) -> PKCanvasView {
        let canvas = PKCanvasView()
        canvas.drawingPolicy = drawingPolicy
        onCanvasCreated(canvas)
        return canvas
    }

    func updateUIView(_ uiView: PKCanvasView, context: Context) {
        // 可在此处根据需求同步视图状态
    }
}

2. 更新ContentView,通过回调获取画布实例

不再传递Binding类型的canvas,改为在视图创建时通过回调将实例赋值给ViewModel:

struct ExperienceDrawingContentView: View {
    @ObservedObject private var viewModel: ExperienceDrawingContentViewModel

    init(viewModel: ExperienceDrawingContentViewModel) {
        self.viewModel = viewModel
    }

    var body: some View {
        DrawingCanvasView(drawingPolicy: .anyInput, onCanvasCreated: { canvas in
            viewModel.canvas = canvas
        })
            .onAppear(perform: viewModel.handleViewDidLoad)
            .navigationTitle("Draw")
            .toolbar {
                Button("Done") {
                    viewModel.handleDone()
                }
            }
    }
}

3. 优化ViewModel的画布属性

将ViewModel中的canvas改为可选类型,避免提前初始化空实例:

class ExperienceDrawingContentViewModel: ObservableObject {
    var canvas: PKCanvasView? // 改为可选类型
    // 其他业务逻辑代码...
}

4. 关闭Metal API Validation(调试优化)

在Xcode的Scheme设置中,进入Run -> Arguments -> Environment Variables,移除METAL_API_VALIDATION_ENABLED或设置其值为NO(发布版会自动关闭该验证)。

现象复现

屏幕闪烁现象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:08:17