如何解决PKToolPicker的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

