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

如何解决PKToolPicker的PKPaletteNamedDefaults缺失默认字典警告?

解决PKToolPicker的「Missing defaults dictionary to restore state for: PKPaletteNamedDefaults」警告

屏幕输出警告:
[ToolPicker] Missing defaults dictionary to restore state for: PKPaletteNamedDefaults

发现只要注释掉showToolPicker()里的if isFirstResponder { canvasView.becomeFirstResponder() }语句,警告就不会触发。推测是初始值设置有误,但找不到PKPaletteNamedDefaults的相关资料,想请教配置PKToolPicker时哪里出错了?

给出的代码:

struct CanvasView {

    @Binding var canvasData: Data
    @Binding var isFirstResponder: Bool
    let onSaved: (Data) -> Void

    @State var toolPicker = PKToolPicker()
    @State var canvasView = PKCanvasView()

}

private extension CanvasView {

    func showToolPicker() {
        toolPicker.overrideUserInterfaceStyle = .light
        toolPicker.setVisible(true, forFirstResponder: canvasView)
        toolPicker.addObserver(canvasView)
        if isFirstResponder { canvasView.becomeFirstResponder() }
    }

}

问题原因

这个警告的核心是PKToolPicker试图恢复调色板状态,但对应的默认配置字典不存在。当调用canvasView.becomeFirstResponder()时,工具选择器会尝试从UserDefaults中加载之前保存的调色板配置,但如果是首次使用或相关配置被清除,就会触发该警告。

解决方法

  • 调整初始化与调用顺序
    确保工具选择器的基础配置在画布成为第一响应者前完成,避免触发未准备好的状态恢复逻辑:

    private func showToolPicker() {
        toolPicker.overrideUserInterfaceStyle = .light
        toolPicker.addObserver(canvasView)
        // 先绑定工具选择器与画布
        toolPicker.setVisible(true, forFirstResponder: canvasView)
        // 只在画布当前不是第一响应者时触发,避免重复调用
        if isFirstResponder && !canvasView.isFirstResponder {
            canvasView.becomeFirstResponder()
        }
    }
    
  • 提前完成工具选择器的初始化
    建议在视图onAppear阶段就完成工具选择器的配置,而不是等到调用showToolPicker()时才处理:

    struct CanvasView: View {
        // 原有属性...
    
        var body: some View {
            // 注意:需要将PKCanvasView包装为UIViewRepresentable才能在SwiftUI中使用
            CanvasRepresentable(canvasView: $canvasView, isFirstResponder: $isFirstResponder)
                .onAppear {
                    setupToolPicker()
                }
        }
    
        private func setupToolPicker() {
            toolPicker.overrideUserInterfaceStyle = .light
            toolPicker.addObserver(canvasView)
            toolPicker.setVisible(true, forFirstResponder: canvasView)
        }
    }
    
    // PKCanvasView的SwiftUI包装器
    struct CanvasRepresentable: UIViewRepresentable {
        @Binding var canvasView: PKCanvasView
        @Binding var isFirstResponder: Bool
    
        func makeUIView(context: Context) -> PKCanvasView {
            canvasView
        }
    
        func updateUIView(_ uiView: PKCanvasView, context: Context) {
            if isFirstResponder != uiView.isFirstResponder {
                isFirstResponder ? uiView.becomeFirstResponder() : uiView.resignFirstResponder()
            }
        }
    }
    
  • 预写入空配置字典(可选)
    如果想彻底消除警告,可以在App启动时提前向UserDefaults写入空的配置字典,避免工具选择器找不到对应键:

    // 在App.swift或初始化代码中调用
    UserDefaults.standard.set([:], forKey: "PKPaletteNamedDefaults")
    

    注意:PKPaletteNamedDefaults是系统内部私有键,苹果可能在后续版本中修改,谨慎使用。

关键说明

PKPaletteNamedDefaults是系统内部用于存储工具选择器调色板预设的键,官方未公开相关文档,找不到资料属于正常情况。该警告本身不影响功能,但通过调整初始化顺序或预配置默认值,可以消除警告。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:25:19