paperkit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePaperKit
PaperKit
Beta-sensitive. PaperKit is new in iOS/iPadOS 26, macOS 26, and visionOS 26. API surface may change. Verify details against current Apple documentation before shipping.
PaperKit provides a unified markup experience — the same framework powering markup in Notes, Screenshots, QuickLook, and Journal. It combines PencilKit drawing with structured markup elements (shapes, text boxes, images, lines) in a single canvas managed by . Requires Swift 6.3 and the iOS 26+ SDK.
PaperMarkupViewControllerBeta版本注意事项:PaperKit是iOS/iPadOS 26、macOS 26和visionOS 26中的新增框架。API范围可能会发生变化。发布前请对照Apple官方文档确认细节。
PaperKit提供统一的标记体验——它是支持“备忘录”“截图”“快速查看”和“日志”应用中标记功能的同款框架。它将PencilKit绘图与结构化标记元素(形状、文本框、图片、线条)整合在由管理的单一画布中。需要Swift 6.3及iOS 26+ SDK。
PaperMarkupViewControllerContents
目录
Setup
设置
PaperKit requires no entitlements or special Info.plist entries.
swift
import PaperKitPlatform availability: iOS 26.0+, iPadOS 26.0+, Mac Catalyst 26.0+, macOS 26.0+, visionOS 26.0+.
Three core components:
| Component | Role |
|---|---|
| Interactive canvas for creating and displaying markup and drawing |
| Data model for serializing all markup elements and PencilKit drawing |
| Insertion UI for adding markup elements |
PaperKit不需要权限或特殊的Info.plist配置项。
swift
import PaperKit平台兼容性:iOS 26.0+、iPadOS 26.0+、Mac Catalyst 26.0+、macOS 26.0+、visionOS 26.0+。
三个核心组件:
| 组件 | 作用 |
|---|---|
| 用于创建和显示标记与绘图的交互式画布 |
| 用于序列化所有标记元素和PencilKit绘图的数据模型 |
| 用于添加标记元素的插入界面 |
PaperMarkupViewController
PaperMarkupViewController
The primary view controller for interactive markup. Provides a scrollable canvas for freeform PencilKit drawing and structured markup elements. Conforms to and .
ObservablePKToolPickerObserver这是交互式标记的主视图控制器,提供可滚动画布以支持自由形式的PencilKit绘图和结构化标记元素。遵循和协议。
ObservablePKToolPickerObserverBasic UIKit Setup
基础UIKit设置
swift
import PaperKit
import PencilKit
import UIKit
class MarkupViewController: UIViewController, PaperMarkupViewController.Delegate {
var paperVC: PaperMarkupViewController!
var toolPicker: PKToolPicker!
override func viewDidLoad() {
super.viewDidLoad()
let markup = PaperMarkup(bounds: view.bounds)
paperVC = PaperMarkupViewController(
markup: markup,
supportedFeatureSet: .latest
)
paperVC.delegate = self
addChild(paperVC)
paperVC.view.frame = view.bounds
paperVC.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(paperVC.view)
paperVC.didMove(toParent: self)
toolPicker = PKToolPicker()
toolPicker.addObserver(paperVC)
paperVC.pencilKitResponderState.activeToolPicker = toolPicker
paperVC.pencilKitResponderState.toolPickerVisibility = .visible
}
func paperMarkupViewControllerDidChangeMarkup(
_ controller: PaperMarkupViewController
) {
guard let markup = controller.markup else { return }
Task { try await save(markup) }
}
}swift
import PaperKit
import PencilKit
import UIKit
class MarkupViewController: UIViewController, PaperMarkupViewController.Delegate {
var paperVC: PaperMarkupViewController!
var toolPicker: PKToolPicker!
override func viewDidLoad() {
super.viewDidLoad()
let markup = PaperMarkup(bounds: view.bounds)
paperVC = PaperMarkupViewController(
markup: markup,
supportedFeatureSet: .latest
)
paperVC.delegate = self
addChild(paperVC)
paperVC.view.frame = view.bounds
paperVC.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(paperVC.view)
paperVC.didMove(toParent: self)
toolPicker = PKToolPicker()
toolPicker.addObserver(paperVC)
paperVC.pencilKitResponderState.activeToolPicker = toolPicker
paperVC.pencilKitResponderState.toolPickerVisibility = .visible
}
func paperMarkupViewControllerDidChangeMarkup(
_ controller: PaperMarkupViewController
) {
guard let markup = controller.markup else { return }
Task { try await save(markup) }
}
}Key Properties
关键属性
| Property | Type | Description |
|---|---|---|
| | The current data model |
| | Currently selected content |
| | Whether the canvas accepts input |
| | Whether the ruler overlay is shown |
| | Active PencilKit drawing tool |
| | Background view rendered beneath markup |
| | Min/max zoom scale |
| | Enabled PaperKit features |
| 属性 | 类型 | 描述 |
|---|---|---|
| | 当前的数据模型 |
| | 当前选中的内容 |
| | 画布是否接受输入 |
| | 是否显示标尺覆盖层 |
| | 活跃的PencilKit绘图工具 |
| | 标记层下方渲染的背景视图 |
| | 最小/最大缩放比例 |
| | 启用的PaperKit功能 |
Touch Modes
触摸模式
PaperMarkupViewController.TouchMode.drawing.selectionswift
paperVC.directTouchMode = .drawing // Finger draws
paperVC.directTouchMode = .selection // Finger selects elements
paperVC.directTouchAutomaticallyDraws = true // System decides based on Pencil statePaperMarkupViewController.TouchMode.drawing.selectionswift
paperVC.directTouchMode = .drawing // 手指用于绘图
paperVC.directTouchMode = .selection // 手指用于选择元素
paperVC.directTouchAutomaticallyDraws = true // 系统根据Pencil状态自动决定Content Background
内容背景
Set any view beneath the markup layer for templates, document pages, or images being annotated:
swift
paperVC.contentView = UIImageView(image: UIImage(named: "template"))可以在标记层下方设置任意视图,用于模板、文档页面或待注释图片:
swift
paperVC.contentView = UIImageView(image: UIImage(named: "template"))Delegate Callbacks
代理回调
| Method | Called when |
|---|---|
| Markup content changes |
| User starts drawing |
| Selection changes |
| Visible frame changes |
| 方法 | 触发时机 |
|---|---|
| 标记内容发生变化时 |
| 用户开始绘图时 |
| 选中内容发生变化时 |
| 可见区域发生变化时 |
PaperMarkup Data Model
PaperMarkup数据模型
PaperMarkupSendablePaperMarkupSendableCreating and Persisting
创建与持久化
swift
// New empty model
let markup = PaperMarkup(bounds: CGRect(x: 0, y: 0, width: 612, height: 792))
// Load from saved data
let markup = try PaperMarkup(dataRepresentation: savedData)
// Save — dataRepresentation() is async throws
func save(_ markup: PaperMarkup) async throws {
let data = try await markup.dataRepresentation()
try data.write(to: fileURL)
}swift
// 新建空模型
let markup = PaperMarkup(bounds: CGRect(x: 0, y: 0, width: 612, height: 792))
// 从已保存的数据加载
let markup = try PaperMarkup(dataRepresentation: savedData)
// 保存 — dataRepresentation()是异步抛出方法
func save(_ markup: PaperMarkup) async throws {
let data = try await markup.dataRepresentation()
try data.write(to: fileURL)
}Inserting Content Programmatically
以编程方式插入内容
swift
// Text box
markup.insertNewTextbox(
attributedText: AttributedString("Annotation"),
frame: CGRect(x: 50, y: 100, width: 200, height: 40),
rotation: 0
)
// Image
markup.insertNewImage(cgImage, frame: CGRect(x: 50, y: 200, width: 300, height: 200), rotation: 0)
// Shape
let shapeConfig = ShapeConfiguration(
type: .rectangle,
fillColor: UIColor.systemBlue.withAlphaComponent(0.2).cgColor,
strokeColor: UIColor.systemBlue.cgColor,
lineWidth: 2
)
markup.insertNewShape(configuration: shapeConfig, frame: CGRect(x: 50, y: 420, width: 200, height: 100), rotation: 0)
// Line with arrow end marker
let lineConfig = ShapeConfiguration(type: .line, fillColor: nil, strokeColor: UIColor.red.cgColor, lineWidth: 3)
markup.insertNewLine(
configuration: lineConfig,
from: CGPoint(x: 50, y: 550), to: CGPoint(x: 250, y: 550),
startMarker: false, endMarker: true
)Shape types: , , , , , , , .
.rectangle.roundedRectangle.ellipse.line.arrowShape.star.chatBubble.regularPolygonswift
// 文本框
markup.insertNewTextbox(
attributedText: AttributedString("Annotation"),
frame: CGRect(x: 50, y: 100, width: 200, height: 40),
rotation: 0
)
// 图片
markup.insertNewImage(cgImage, frame: CGRect(x: 50, y: 200, width: 300, height: 200), rotation: 0)
// 形状
let shapeConfig = ShapeConfiguration(
type: .rectangle,
fillColor: UIColor.systemBlue.withAlphaComponent(0.2).cgColor,
strokeColor: UIColor.systemBlue.cgColor,
lineWidth: 2
)
markup.insertNewShape(configuration: shapeConfig, frame: CGRect(x: 50, y: 420, width: 200, height: 100), rotation: 0)
// 带箭头末端标记的线条
let lineConfig = ShapeConfiguration(type: .line, fillColor: nil, strokeColor: UIColor.red.cgColor, lineWidth: 3)
markup.insertNewLine(
configuration: lineConfig,
from: CGPoint(x: 50, y: 550), to: CGPoint(x: 250, y: 550),
startMarker: false, endMarker: true
)形状类型:、、、、、、、。
.rectangle.roundedRectangle.ellipse.line.arrowShape.star.chatBubble.regularPolygonOther Operations
其他操作
swift
markup.append(contentsOf: otherMarkup) // Merge another PaperMarkup
markup.append(contentsOf: pkDrawing) // Merge a PKDrawing
markup.transformContent(CGAffineTransform(...)) // Apply affine transform
markup.removeContentUnsupported(by: featureSet) // Strip unsupported elements| Property | Description |
|---|---|
| Coordinate space of the markup |
| Tight bounding box of all content |
| Features used by this data model's content |
| Extractable text for search indexing |
Use on the view controller to get a frame that avoids overlapping existing content.
suggestedFrameForInserting(contentInFrame:)swift
markup.append(contentsOf: otherMarkup) // 合并另一个PaperMarkup
markup.append(contentsOf: pkDrawing) // 合并PKDrawing
markup.transformContent(CGAffineTransform(...)) // 应用仿射变换
markup.removeContentUnsupported(by: featureSet) // 移除不支持的元素| 属性 | 描述 |
|---|---|
| 标记的坐标空间 |
| 所有内容的紧密边界框 |
| 此数据模型内容使用的功能集 |
| 可提取用于搜索索引的文本 |
可以使用视图控制器的方法获取一个避免与现有内容重叠的插入区域。
suggestedFrameForInserting(contentInFrame:)Insertion Controllers
插入控制器
MarkupEditViewController (iOS, iPadOS, visionOS)
MarkupEditViewController(iOS、iPadOS、visionOS)
Presents a popover menu for inserting shapes, text boxes, lines, and other elements.
swift
func showInsertionMenu(from barButtonItem: UIBarButtonItem) {
let editVC = MarkupEditViewController(
supportedFeatureSet: .latest,
additionalActions: []
)
editVC.delegate = paperVC // PaperMarkupViewController conforms to the delegate
editVC.modalPresentationStyle = .popover
editVC.popoverPresentationController?.barButtonItem = barButtonItem
present(editVC, animated: true)
}弹出菜单,用于插入形状、文本框、线条等元素。
swift
func showInsertionMenu(from barButtonItem: UIBarButtonItem) {
let editVC = MarkupEditViewController(
supportedFeatureSet: .latest,
additionalActions: []
)
editVC.delegate = paperVC // PaperMarkupViewController遵循此代理协议
editVC.modalPresentationStyle = .popover
editVC.popoverPresentationController?.barButtonItem = barButtonItem
present(editVC, animated: true)
}MarkupToolbarViewController (macOS, Mac Catalyst)
MarkupToolbarViewController(macOS、Mac Catalyst)
Provides a toolbar with drawing tools and insertion buttons.
swift
let toolbar = MarkupToolbarViewController(supportedFeatureSet: .latest)
toolbar.delegate = paperVC
addChild(toolbar)
toolbar.view.frame = toolbarContainerView.bounds
toolbarContainerView.addSubview(toolbar.view)
toolbar.didMove(toParent: self)Both controllers must use the same as the .
FeatureSetPaperMarkupViewController提供包含绘图工具和插入按钮的工具栏。
swift
let toolbar = MarkupToolbarViewController(supportedFeatureSet: .latest)
toolbar.delegate = paperVC
addChild(toolbar)
toolbar.view.frame = toolbarContainerView.bounds
toolbarContainerView.addSubview(toolbar.view)
toolbar.didMove(toParent: self)两个控制器必须与使用相同的。
PaperMarkupViewControllerFeatureSetFeatureSet Configuration
FeatureSet配置
FeatureSet| Preset | Description |
|---|---|
| All current features — recommended starting point |
| Features from version 1 |
| No features enabled |
FeatureSet| 预设 | 描述 |
|---|---|
| 包含所有当前功能——推荐作为初始配置 |
| 包含版本1的功能 |
| 未启用任何功能 |
Customizing
自定义配置
swift
var features = FeatureSet.latest
features.remove(.stickers)
features.remove(.images)
// Or build up from empty
var features = FeatureSet.empty
features.insert(.drawing)
features.insert(.text)
features.insert(.shapeStrokes)swift
var features = FeatureSet.latest
features.remove(.stickers)
features.remove(.images)
// 或者从空集开始构建
var features = FeatureSet.empty
features.insert(.drawing)
features.insert(.text)
features.insert(.shapeStrokes)Available Features
可用功能
| Feature | Description |
|---|---|
| Freeform PencilKit drawing |
| Text box insertion |
| Image insertion |
| Sticker insertion |
| Link annotations |
| Loupe/magnifier elements |
| Shape outlines |
| Shape fills |
| Shape opacity control |
| 功能 | 描述 |
|---|---|
| 自由形式的PencilKit绘图 |
| 插入文本框 |
| 插入图片 |
| 插入贴纸 |
| 链接注释 |
| 放大镜元素 |
| 形状轮廓 |
| 形状填充 |
| 形状透明度控制 |
HDR Support
HDR支持
Set above on both the and :
colorMaximumLinearExposure1.0FeatureSetPKToolPickerswift
var features = FeatureSet.latest
features.colorMaximumLinearExposure = 4.0
toolPicker.maximumLinearExposure = features.colorMaximumLinearExposureUse to match the device screen's capability. Use for SDR-only.
view.window?.windowScene?.screen.potentialEDRHeadroom1.0在和上将设置为大于的值:
FeatureSetPKToolPickercolorMaximumLinearExposure1.0swift
var features = FeatureSet.latest
features.colorMaximumLinearExposure = 4.0
toolPicker.maximumLinearExposure = features.colorMaximumLinearExposure可以使用来匹配设备屏幕的能力。仅支持SDR的设备使用。
view.window?.windowScene?.screen.potentialEDRHeadroom1.0Shapes, Inks, and Line Markers
形状、墨水和线条标记
swift
features.shapes = [.rectangle, .ellipse, .arrowShape, .line]
features.inks = [.pen, .pencil, .marker]
features.lineMarkerPositions = .all // .single, .double, .plain, or .allswift
features.shapes = [.rectangle, .ellipse, .arrowShape, .line]
features.inks = [.pen, .pencil, .marker]
features.lineMarkerPositions = .all // .single、.double、.plain或.allIntegration with PencilKit
与PencilKit集成
PaperKit accepts for drawing and can append content.
PKToolPKDrawingswift
import PencilKit
// Set drawing tool
paperVC.drawingTool = PKInkingTool(.pen, color: .black, width: 3)
// Merge existing PKDrawing into markup
markup.append(contentsOf: existingPKDrawing)PaperKit接受用于绘图,并且可以追加内容。
PKToolPKDrawingswift
import PencilKit
// 设置绘图工具
paperVC.drawingTool = PKInkingTool(.pen, color: .black, width: 3)
// 将现有PKDrawing合并到标记中
markup.append(contentsOf: existingPKDrawing)Tool Picker Setup
工具选择器设置
swift
let toolPicker = PKToolPicker()
toolPicker.addObserver(paperVC)
paperVC.pencilKitResponderState.activeToolPicker = toolPicker
paperVC.pencilKitResponderState.toolPickerVisibility = .visibleSetting to keeps the picker functional (responds to Pencil gestures) but not visible, enabling the mini tool picker experience.
toolPickerVisibility.hiddenswift
let toolPicker = PKToolPicker()
toolPicker.addObserver(paperVC)
paperVC.pencilKitResponderState.activeToolPicker = toolPicker
paperVC.pencilKitResponderState.toolPickerVisibility = .visible将设置为会使选择器保持功能可用(响应Pencil手势)但不可见,从而实现迷你工具选择器的体验。
toolPickerVisibility.hiddenContent Version Compatibility
内容版本兼容性
FeatureSet.ContentVersionPKContentVersionswift
let pkVersion = features.contentVersion.pencilKitContentVersionFeatureSet.ContentVersionPKContentVersionswift
let pkVersion = features.contentVersion.pencilKitContentVersionSwiftUI Integration
SwiftUI集成
Wrap in :
PaperMarkupViewControllerUIViewControllerRepresentableswift
struct MarkupView: UIViewControllerRepresentable {
@Binding var markup: PaperMarkup
func makeUIViewController(context: Context) -> PaperMarkupViewController {
let vc = PaperMarkupViewController(markup: markup, supportedFeatureSet: .latest)
vc.delegate = context.coordinator
let toolPicker = PKToolPicker()
toolPicker.addObserver(vc)
vc.pencilKitResponderState.activeToolPicker = toolPicker
vc.pencilKitResponderState.toolPickerVisibility = .visible
context.coordinator.toolPicker = toolPicker
return vc
}
func updateUIViewController(_ vc: PaperMarkupViewController, context: Context) {
if vc.markup != markup { vc.markup = markup }
}
func makeCoordinator() -> Coordinator { Coordinator(parent: self) }
class Coordinator: NSObject, PaperMarkupViewController.Delegate {
let parent: MarkupView
var toolPicker: PKToolPicker?
init(parent: MarkupView) { self.parent = parent }
func paperMarkupViewControllerDidChangeMarkup(
_ controller: PaperMarkupViewController
) {
if let markup = controller.markup { parent.markup = markup }
}
}
}将包装在中:
PaperMarkupViewControllerUIViewControllerRepresentableswift
struct MarkupView: UIViewControllerRepresentable {
@Binding var markup: PaperMarkup
func makeUIViewController(context: Context) -> PaperMarkupViewController {
let vc = PaperMarkupViewController(markup: markup, supportedFeatureSet: .latest)
vc.delegate = context.coordinator
let toolPicker = PKToolPicker()
toolPicker.addObserver(vc)
vc.pencilKitResponderState.activeToolPicker = toolPicker
vc.pencilKitResponderState.toolPickerVisibility = .visible
context.coordinator.toolPicker = toolPicker
return vc
}
func updateUIViewController(_ vc: PaperMarkupViewController, context: Context) {
if vc.markup != markup { vc.markup = markup }
}
func makeCoordinator() -> Coordinator { Coordinator(parent: self) }
class Coordinator: NSObject, PaperMarkupViewController.Delegate {
let parent: MarkupView
var toolPicker: PKToolPicker?
init(parent: MarkupView) { self.parent = parent }
func paperMarkupViewControllerDidChangeMarkup(
_ controller: PaperMarkupViewController
) {
if let markup = controller.markup { parent.markup = markup }
}
}
}Common Mistakes
常见错误
Mismatched FeatureSets
不匹配的FeatureSet
swift
// DON'T
let paperVC = PaperMarkupViewController(markup: m, supportedFeatureSet: .latest)
let editVC = MarkupEditViewController(supportedFeatureSet: .version1, additionalActions: [])
// DO — use the same FeatureSet for both
let features = FeatureSet.latest
let paperVC = PaperMarkupViewController(markup: m, supportedFeatureSet: features)
let editVC = MarkupEditViewController(supportedFeatureSet: features, additionalActions: [])swift
// 错误示例
let paperVC = PaperMarkupViewController(markup: m, supportedFeatureSet: .latest)
let editVC = MarkupEditViewController(supportedFeatureSet: .version1, additionalActions: [])
// 正确示例 — 两者使用相同的FeatureSet
let features = FeatureSet.latest
let paperVC = PaperMarkupViewController(markup: m, supportedFeatureSet: features)
let editVC = MarkupEditViewController(supportedFeatureSet: features, additionalActions: [])Ignoring Content Version on Load
加载时忽略内容版本
swift
// DON'T
let markup = try PaperMarkup(dataRepresentation: data)
paperVC.markup = markup
// DO — check version compatibility
let markup = try PaperMarkup(dataRepresentation: data)
if markup.featureSet.isSubset(of: paperVC.supportedFeatureSet) {
paperVC.markup = markup
} else {
showVersionMismatchAlert()
}swift
// 错误示例
let markup = try PaperMarkup(dataRepresentation: data)
paperVC.markup = markup
// 正确示例 — 检查版本兼容性
let markup = try PaperMarkup(dataRepresentation: data)
if markup.featureSet.isSubset(of: paperVC.supportedFeatureSet) {
paperVC.markup = markup
} else {
showVersionMismatchAlert()
}Blocking Main Thread with Serialization
使用序列化阻塞主线程
swift
// DON'T — dataRepresentation() is async, don't try to work around it
// DO — save from an async context
func paperMarkupViewControllerDidChangeMarkup(_ controller: PaperMarkupViewController) {
guard let markup = controller.markup else { return }
Task {
let data = try await markup.dataRepresentation()
try data.write(to: fileURL)
}
}swift
// 错误示例 — dataRepresentation()是异步方法,不要尝试绕过它
// 正确示例 — 在异步上下文执行保存
func paperMarkupViewControllerDidChangeMarkup(_ controller: PaperMarkupViewController) {
guard let markup = controller.markup else { return }
Task {
let data = try await markup.dataRepresentation()
try data.write(to: fileURL)
}
}Forgetting to Retain the Tool Picker
忘记保留工具选择器
swift
// DON'T — local variable gets deallocated
func viewDidLoad() {
let toolPicker = PKToolPicker()
toolPicker.addObserver(paperVC)
}
// DO — store as instance property
var toolPicker: PKToolPicker!swift
// 错误示例 — 局部变量会被释放
func viewDidLoad() {
let toolPicker = PKToolPicker()
toolPicker.addObserver(paperVC)
}
// 正确示例 — 存储为实例属性
var toolPicker: PKToolPicker!Wrong Insertion Controller for Platform
为平台选择错误的插入控制器
swift
// DON'T — MarkupEditViewController is iOS/iPadOS/visionOS only
// DO
#if os(macOS)
let toolbar = MarkupToolbarViewController(supportedFeatureSet: features)
#else
let editVC = MarkupEditViewController(supportedFeatureSet: features, additionalActions: [])
#endifswift
// 错误示例 — MarkupEditViewController仅适用于iOS/iPadOS/visionOS
// 正确示例
#if os(macOS)
let toolbar = MarkupToolbarViewController(supportedFeatureSet: features)
#else
let editVC = MarkupEditViewController(supportedFeatureSet: features, additionalActions: [])
#endifReview Checklist
检查清单
- present; deployment target is iOS 26+ / macOS 26+ / visionOS 26+
import PaperKit - initialized with bounds matching content size
PaperMarkup - Same used for
FeatureSetand insertion controllerPaperMarkupViewController - called in async context
dataRepresentation() - retained as a stored property
PKToolPicker - Delegate set on for change callbacks
PaperMarkupViewController - Content version checked when loading saved data
- Correct insertion controller per platform (vs
MarkupEditViewController)MarkupToolbarViewController - cases handled on deserialization
MarkupError - HDR: set on both
colorMaximumLinearExposureandFeatureSetPKToolPicker
- 已添加;部署目标为iOS 26+ / macOS 26+ / visionOS 26+
import PaperKit - 初始化时使用的边界与内容尺寸匹配
PaperMarkup - 和插入控制器使用相同的
PaperMarkupViewControllerFeatureSet - 在异步上下文调用
dataRepresentation() - 被存储为实例属性
PKToolPicker - 已为设置代理以接收变更回调
PaperMarkupViewController - 加载已保存数据时检查版本兼容性
- 根据平台选择正确的插入控制器(vs
MarkupEditViewController)MarkupToolbarViewController - 反序列化时处理情况
MarkupError - HDR支持:在和
FeatureSet上都设置了PKToolPickercolorMaximumLinearExposure
References
参考资料
- PaperKit documentation
- Integrating PaperKit into your app
- Meet PaperKit — WWDC25
- The skill covers PencilKit drawing, tool pickers, and PKDrawing serialization
pencilkit - references/paperkit-patterns.md — data persistence, rendering, multi-platform setup, custom feature sets
- PaperKit文档
- 在应用中集成PaperKit
- WWDC25:初识PaperKit
- 技能涵盖PencilKit绘图、工具选择器和PKDrawing序列化
pencilkit - references/paperkit-patterns.md — 数据持久化、渲染、多平台设置、自定义功能集