Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Effective PencilKit / 新聞スクラップ体験の実現

Go Takagi
September 12, 2022

Effective PencilKit / 新聞スクラップ体験の実現

iOSDC2022 Day 2 Track B 13:00〜
Effective PencilKit / 新聞スクラップ体験の実現

WWDC 2019 で発表された PencilKit を利用することで、数行のコードで 標準メモアプリと同様の手描き体験をアプリに導入できます。

発表に先立ち、日本経済新聞社の紙面ビューアーアプリでは、Apple Pencil を用いた紙面画像にメモやハイライトを書き込める機能をリリースしました。

アプリの機能要件を満たすための独自拡張の実現には、様々な制約が立ちはだかりました。
たとえば、キャンバスに画像を載せる、ズームやスクロールなどビューアーとしての操作は残しつつ書き込みを一時的に無効にするなど、一見すると単純そうですが一筋縄ではいきません。

本セッションでは PencilKit の開発ノウハウを、ドキュメントと内部の動きから洞察した知見の両面から解説します。開発経験を踏まえ、紙の新聞に書き込みを行うユーザー体験をどのようにアプリへ落とし込んでいったか説明できればと思います。

Go Takagi

September 12, 2022
Tweet

More Decks by Go Takagi

Other Decks in Technology

Transcript

  1. E ff ective PencilKit 新聞スクラップ体験の実現 Go Takagi 20 22 /

    09 / 12 iOSDC JAPAN 2 022 Day 2 #Track B 13 : 0 0 〜
  2. Me ( Go Takagi ) ‣ID • shimastripe / shimastriper

    ‣Work • 株式会社 ⽇本経済新聞社 ‣ iOS 紙⾯ビューアーアプリ の開発を担当 • iOSDC NOC チーム ‣Like • 柴⽝が⼤好きです! 2 2年ぶりにカムバックです!
  3. Keynote ‣PencilKit を拡張する • Example より更に先のユースケースへ対応 ‣Points • PencilKit で

    Preview / Edit できる画⾯ • 独⾃のペンツールを統合 • テキストハイライト機能 • ツールパレット • Test‧その他Tips 3
  4. Introduction

  5. 紙⾯ビューアー: 新聞紙⾯画像に特化 ‣紙⾯画像形式で読める • 縦 (+ 横) 書き 両対応 •

    iPad 利⽤者多い • オフライン動作 • Wi-Fi で夜間に⾃動DL • iOSDC 2 0 2 0 もぜひ 🙏 5 AppStore ページより
  6. 紙⾯画像に描き込みを⾏いたい! 6 Zoom や Scroll ができる

  7. 紙⾯画像への描き込み => スクラップ体験 ‣デジタルでも実現したい • 紙に描いて残す体験を再現 ‣App単体では実現できなかった • Evernote export

    越しのみ • (現在はこの機能は終了) 7 https://prtimes.jp/main/html/rd/p/ 0 0 00 0 0 01 9 . 0 00 0 1 1 11 5 .html
  8. Apple Pencil で描けるメモ機能をリリース 8 https://www.youtube.com/watch?v=JwltoOq_JeU

  9. Apple Pencil を⽤いた⾃由描画 9 ‣iPhone は指で描画可能

  10. 描いたメモは保存(ロック)し、表⽰+⾮表⽰できる ‣編集モードが切り替えできる • Preview / Edit • Preview 中は Scroll

    / Zoom のみ可能 ‣描き込み表⽰が切り替えできる • 描き込み ON / OFF ‣保存したデータはSyncされる • 端末をまたいで描き込みメモが残せる 1 0
  11. 段落も考慮した本⽂のハイライトマーカー ‣独⾃ペンツールを統合 • HighlightKit を内製 • Canvas に共存して利⽤可能に 1 1

  12. PencilKit でどうやるの...? ‣本セッション: PencilKit の拡張⽅法を学んでいきます • PencilKit のユースケースを広げる拡張を紹介! ‣deploymentTarget •

    iOS 1 4 + • iPadOS 1 4 + 1 2
  13. PencilKit

  14. WWDC: 19 登場 ‣3⾏のコードで Apple Pencil 描き込み体験を実現 • キャンバスの作成 •

    ビュー階層の追加 • Ink の選択 ‣iPad だけでなく iPhone も可能 • 指で描き込み 1 4 let canvas = PKCanvasView(frame: view.frame) view.addSubview(canvas) canvas.tool = PKInkingTool(.pen, color: .black, width: 30)
  15. Apple Pencil ‣低レイテンシ • 1秒間に240回スキャニングして情報を送る (240 Hz) • 描いたイメージとディスプレイへの描画遅れが極⼩ ‣たくさんの情報

    • altitude (⾼度) / pressure (圧⼒) / azimuth (⽅位) ‣Scribble による⼿書き認識 (iOS 1 4 +) • タブレットの⼊⼒⽅法に新しい体験 1 5
  16. PencilKit のここが凄い! ‣Apple Pencil 体験を容易に導⼊できる • OS 標準の Canvas が再現できる

    ‣低レイテンシ • Pencil から送られる⼊⼒を素早く画⾯に反映 • Metal の API を⽤いたレンダリング ‣描画したものが構造的なデータで表されている • 永続化して再編集可能 ‣Image形式で出⼒可能 • サムネイル画像が⽣成できる 1 6 WWDC: 1 9 Introducing PencilKit
  17. 独⾃実装する場合 (≠ PencilKit ) ‣UIKit のタッチイベントは 60 Hz • 精度⾼く滑らかに描画するために、2種類のデータをハンドリングする

    • 予測値を受けとって爆速描画‧遅れて来る実測値を更新反映 (補正) • ⼀筋縄ではいかない!PencilKit とても便利 1 7 https://developer.apple.com/documentation/uikit/pencil_interactions/handling_input_from_apple_pencil https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_touches_in_your_view/getting_high- fi delity_input_with_coalesced_touches
  18. Example App: Drawing with PencilKit ‣⼀通りまとまってる • Canvas を表⽰する •

    描き込み領域の⾃動拡張⽅法 • ペンのツールパレットを表⽰する • Undo / Redo • 署名 (Signature) • サムネイル⽣成 • PKDrawing (描き込みデータ) の永続化 1 8 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit ⼀通りアプリが作れそう!
  19. Example 以上のことできなくない......?🤔 ‣⼀通りリッチに機能はあるけど • Example 以上のものを作れない • 絶妙にやりたいことに⼿が届かない 1 9

    と思ったのは⾃分だけじゃない......はず??
  20. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 2 0
  21. できる拡張を探して実現していく ‣View の構造に着⽬ • PencilKit の性質から構造を推測 • 可能そうな拡張⽅法を試していく ‣PencilKit の資産を活かしてアプリが作れる

    • ユースケースを満たしつつ、再実装を避ける 2 1
  22. Example を通して PencilKit を紹介

  23. ⼤まかな構成 ‣PKCanvasView • キャンバスとなる UIScrollView ‣PKToolPicker • ペンツール (ペン‧鉛筆‧消しゴム‧定規) •

    PKTool: PKInkingTool / PKEraserTool / PKLassoTool ‣PKDrawing • 描き込みデータを表す構造体‧ストロークのパスも取れる • Codable に対応、永続化‧復元が容易にできる • UIImage への変換も可能 2 3 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit
  24. 拾えるイベント ‣PKCanvasViewDelegate • UIScrollViewDelegate • PKDrawing 周りの変更イベント • Tool を使って描き始め

    / 終わり ‣PKToolPickerObserver • ToolPicker の選択 / 移動 / 表⽰ 2 4 ダークモードだと⾊が反転 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit
  25. Example から学べること ‣⼀連の描き込み体験は作れる • 描き込みキャンバスの実現 • Drawing の変更時に Undo /

    Redo を適宜更新 • 余⽩が狭くなったらキャンバスサイズの更新 • リアルタイムで更新して無限キャンバスも • Canvas をカスタマイズする要素は⾒当たらない • Canvasにイメージを⼊れる⽅法はわからない...... ‣永続化‧画像化 • PKDrawing を Data に変換して保存 • UIImage を書き出して保存 2 5
  26. 拡張に取り組んでいく

  27. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 2 7
  28. 画像へ描き込みを実現したい

  29. UIImageView in UIScrollView ‣⼤きいコンテンツを部分的に表⽰するカメラ(View) • ContentView: ScrollView の subview •

    Zoomやスクロール、余⽩をカスタマイズできる 2 9 https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html
  30. 既存紙⾯画像ページ: ⼀般的なImageViewer ‣UIScrollView の中に Image • ズーム‧スクロールができる • 画像は3段階の画質をサポート ‣カスタマイズ

    • ダブルタップでカスタムジェスチャー • 横書きモードの表⽰‧保存‧共有 • iPad SplitView 3 0 UIScrollView
  31. ImageViewer に描き込みを⾏いたい ‣ImageViewer に PKCanvasView ( UIScrollView ) を重ねる •

    重ねて同時に操作してみる? 3 1 UIScrollView PKCanvasView
  32. 失敗......というか断念

  33. 2枚の同期が難しい ‣Zoom の調整 • ContentView 同⼠のサイズが違うと、 Zoom する⼤きさや位置が変わる • iPhone,

    iPad, SplitView でも対応しないといけない ‣PencilKit 側の描画が遅れる • 別の View 越しにイベントを伝えているため? • ⽬で⾒てアウトな品質に ‣何より管理が複雑 • 機能追加するたびに UIScrollView が増えたりしたら......⽅針を変える 3 3
  34. PKCanvasView = UIScrollView ‣UIScrollView として観察してみる • ContentView = 描き込み領域? •

    発⾒できれば • ContentView に Image を Insert できないか • 実現できれば ScrollView 1 枚化ができそう 3 4 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit
  35. Debug Hierarchy で覗いてみる ‣PKCanvasView の subviews には • UIView (

    ContentView っぽい) • subviews に PKCanvasAttachmentView • PKTiledCanvasView (hidden) • PKTiledView • PKSelectionGestureView • _UIScrollViewScrollIndicator * 2 • スクロールインジケーター 3 5
  36. Debug Hierarchy で覗いてみる ‣PKCanvasView の subviews には • UIView (

    ContentView っぽい) • subviews に PKCanvasAttachmentView • PKTiledCanvasView (hidden) • PKTiledView • PKSelectionGestureView • _UIScrollViewScrollIndicator * 2 • スクロールインジケーター 3 6
  37. (参考までに) UIScrollView の場合は ‣構造が似ている • UIImageView ( ContentView ) •

    _UIScrollViewScrollIndicator * 2 • スクロールインジケーター 3 7
  38. ContentView? に View を⼊れてみる ‣PKCanvasView • backgroundColor = .systemRed ‣UIImageView

    を⼊れてみる • ContentView に Insert 3 8
  39. Drawing 中 背景⾊になってしまう ‣PKCanvasView • PKCanvasAttachment の tintColor と連携? •

    backgroundColor = .clear にしてみると....... ‣UIImageView と 背景 UIView • ContentView に Insert • 必要あれば背景 View を追加で Insert 3 9
  40. 画像の上に描き込みができる! ‣ScrollやZoomも滑らか!ズレない! • 描き込み領域は • canvasView.contentSize を設定して調整可能 • ImageSize から必要な余⽩を計算し、contentSize

    にする ‣3種類の画質の画像と合成 • PKDrawing と画像を分けて保存 • 画像サイズに応じて倍率を計算し、Drawingと重ねる 4 0
  41. (再掲) 既存紙⾯画像ページ: ⼀般的なImageViewer ‣UIScrollView の中に Image • ズーム‧スクロールができる • 画像は3段階の画質をサポート

    ‣カスタマイズ • ダブルタップでカスタムジェスチャー • 横書きモードの表⽰‧保存‧共有 • iPad SplitView 4 1 UIScrollView
  42. PKCanvasView で UIScrollView + α (移植)! ‣PKCanvasView の中に Image •

    ズーム‧スクロールができる • 画像は3段階の画質をサポート ‣カスタマイズ (移植) • ダブルタップでカスタムジェスチャー • 横書きモードの表⽰‧保存‧共有 • iPad SplitView 4 2 PKCanvasView
  43. 4 3 PencilKit! UIScrollView PKCanvasView

  44. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 4 4
  45. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 4 5
  46. Preview / Edit の切り替え

  47. Canvas を Preview / Edit 切り替えする ‣メモアプリ • Preview は1本指でスクロール

    • Edit は、1本指で描画、2本でスクロール ‣描き込みだけ OFF にするには canvasView.isUserInteractionEnabled = false • 全ての Gesture が動かなくなる....... canvasView.drawingGestureRecognizer.isEnabled • Drawing に関する操作だけ Disabled にできる 4 7 Preview Edit ❌ ⭕
  48. 4 8 PencilKit! UIScrollView PKCanvasView

  49. 4 9 Draw ON Draw OFF Pencil で描ける! スクロール操作のみできる Edit

    Preview UIScrollView PKCanvasView の描き込みモードを切り替える
  50. 5 0 Pencil で描ける! スクロール操作のみできる ダブルタップや保存‧共有機能を移植する! Edit Preview Draw ON

    Draw OFF
  51. 描き込み内容の⼀時⾮表⽰ ‣PKCanvasAttachmentView の hidden で可能 5 1 Hidden Appear

  52. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 5 2
  53. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 5 3
  54. 独⾃マーカーの実装 ‣テキストハイライト • 本⽂に沿って • 滑らかに綺麗に 5 4 PencilKitのマーカーでは 滲んで⾒えてしまう

  55. HighlightKit を開発 ‣滑らかなテキストマーカー • 1⽂字ごとの個別サイズに対応 • 段落を考慮してハイライト ‣拡張機能をモジュールで⽤意 • SPM

    Package で実現 5 5
  56. 独⾃マーカー⽤の View も ContentView に⼊れる ‣PKCanvasView を UIScrollView として更に使う! •

    ContentView • CanvasBackgroundView • ImageView • PKCanvasAttachmentView • HighlightView • PKTiledCanvasView (hidden) • ...etc. 5 6
  57. 独⾃マーカー⽤の View も ContentView に⼊れる ‣PKCanvasView を UIScrollView として更に使う! •

    ContentView • CanvasBackgroundView • ImageView • PKCanvasAttachmentView • HighlightView • PKTiledCanvasView (hidden) • ...etc. 5 7 台紙となる背景 紙⾯画像 ⼿描き領域 独⾃マーカー
  58. 5 8 Pencil で描ける! スクロール操作のみできる Edit Preview Draw ON Draw

    OFF Highlight Draw OFF Draw ON 独⾃マーカー!
  59. Highlightの仕組み ‣始点と終点をキャプチャ • 間にある番号をすべて塗る 5 9 ① ② ③ ④

    ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ㉑ ㉒ ㉓ ㉔ ㉕ ㉖ ㉗ ㉘ ㉙ ㉚ ㉛ ㉜ ㉝ ㉞ ㉟ ㊱ ㊲ ㊳ ㊴ ㊵ ㊶ ㊷ ㊸ ㊹ ㊺ ㊻ ㊼ ㊽ ㊾ ㊿
  60. ポインタが ① から ⑯ へいったら ‣始点と終点をキャプチャ • 間にある番号をすべて塗る 6 0

    ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ㉑ ㉒ ㉓ ㉔ ㉕ ㉖ ㉗ ㉘ ㉙ ㉚ ㉛ ㉜ ㉝ ㉞ ㉟ ㊱ ㊲ ㊳ ㊴ ㊵ ㊶ ㊷ ㊸ ㊹ ㊺ ㊻ ㊼ ㊽ ㊾ ㊿
  61. ポインタが ㉖ から ㊳ へいったら ‣段落をまたいでもハイライトできる • データ側で順序を計算しておく 6 1

    ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ㉑ ㉒ ㉓ ㉔ ㉕ ㉖ ㉗ ㉘ ㉙ ㉚ ㉛ ㉜ ㉝ ㉞ ㉟ ㊱ ㊲ ㊳ ㊴ ㊵ ㊶ ㊷ ㊸ ㊹ ㊺ ㊻ ㊼ ㊽ ㊾ ㊿
  62. 新聞画像のテキスト領域の抽出 ‣既存の OCR の精度で限界 • OCRとは画像から⽂字の領域と内容を抽出する技術のこと • 新聞特有の性質と相性が悪かった • 可変幅フォント

    • 組み⽂字 • 段落順序がバラバラ • (直感的でない) • 技術的制約で⽂字埋め込みのPDFの使⽤は困難 6 2
  63. 新聞縦書き向け⽂字座標抽出ロジックを開発 6 3 Google Cloud Vision API 開発した⼿法 ※ 2022年04⽉時点

  64. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 6 4
  65. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 6 5
  66. PKToolPicker

  67. PKToolPicker ‣メモの Tool パレットを利⽤可能! • iPhone / iPad で機能差があることに注意 •

    iPhone は「Undo‧Redo」がついていない • 3本指で左から右にスワイプすると同じジェスチャーがあります 6 7
  68. Phone モードでは個別に⽤意を検討 ‣HIG で指摘されていました 6 8 https://developer.apple.com/design/human-interface-guidelines/inputs/apple-pencil-and-scribble

  69. ほとんどカスタムできない ‣⼀部の設定の ON / OFF のみ • 定規を表⽰するか • 指で描画を許可する設定を出すかどうか

    ‣CustomTool の追加‧削除 • できない、特定のTool だけ表⽰は無理 6 9 マーカーだけ独⾃実装のものにしたいが...
  70. ToolPicker を完全に⾃作すればやれる....... ‣標準 ToolPicker を外から操作する • PKCanvasView.tool / PKToolPicker.selectedTool を上書き

    ‣独⾃ツールも⼊ったツールパレットを作りたい場合 • 完全⾃作して UI を作る • 各種ボタンで Gesture をうまく切り替える • PKCanvasView の描き込み Gesture を ON/OFF • Custom Tool の Gesture を ON/OFF 7 0
  71. UISegmentControl 越しに切り替えてみる 7 1 let control = UISegmentedControl(frame: .null, actions:

    [ .init(title: "ϖϯ", handler: { _ in self.toolPicker.selectedTool = PKInkingTool(.pen) }), .init(title: "ϚʔΧʔ", handler: { _ in self.toolPicker.selectedTool = PKInkingTool(.marker) }), .init(title: "Ԗච", handler: { _ in self.toolPicker.selectedTool = PKInkingTool(.pencil) }), ])
  72. PKToolPicker のカスタマイズ情報 ‣UserDefaults に保存 • ユーザーが意図的に変えたか判断できる • 複数プリセットも⽤意可能 • PKToolPicker

    の stateAutosaveName を上書きする 7 2
  73. もっともっと拡張したい ‣PencilKit の Drawing 体験を拡張したい • 画像に対して描き込み • 保存して描き込みを無効化 •

    描き込みの表⽰‧⾮表⽰切り替え ‣独⾃実装したペンツールを統合したい • 本⽂ハイライトマーカー ‣ツールパレットのカスタマイズ • ToolPickerをカスタマイズしたい 7 3
  74. Testing

  75. 拡張したPKCanvasViewをテストする ‣PKCanvasView の subviews の構造チェック • 想定と変わっていないことを確認 • Private Class

    なので Test のみで厳密にチェックする 7 5 let vc = ArticleCanvasViewController() vc.loadView() vc.viewDidLoad() // Private APIͳͷͰຊମίʔυʹೖΕͳ͍Α͏ʹ஫ҙ XCTAssertEqual(NSStringFromClass(type(of: vc.canvasView.subviews[0])), "UIView") XCTAssertEqual(NSStringFromClass(type(of: vc.canvasView.subviews[1])), "PKTiledCanvasView") XCTAssertEqual(NSStringFromClass(type(of: vc.canvasView.subviews[2])), "PKTiledView") XCTAssertEqual(NSStringFromClass( type(of: vc.canvasView.attachmentView)), "PKCanvasAttachmentView")
  76. 他にもカスタマイズした設定があれば Assert ‣ペンツールの設定 • PKDrawing / PKToolPicker は Equatable に準拠

    • AssertionTest が書きやすい • 初期選択ツールのチェック • ユーザー選択後はそちらが維持されるチェック 7 6
  77. PKDrawingと画像の合成テスト ‣合成がズレていないかテストしたい • 描き込みデータを複数サイズの画像とマージ • 3段階の画質 • iPhone / iPad

    の⾒た⽬ 7 7 3段階のサイズ と合体する
  78. ビジュアルリグレッションテスト ‣ 視覚の回帰テスト • View 単位でデグレを検知 • スクリーンショットの Di ff

    を⽤いた差分検知 など • uber/ios-snapshot-test-case や pointfreeco/swift-snapshot-testing が有名 7 8 A A' A'
  79. PKDrawing は Codable に対応 ‣特定の描き込み状態を⽤意に再現可能 • Data 型から復元して、Canvasに適⽤した画⾯を⽐較 • 同じに⾒えて紙⾯画像は

    3 種類別サイズ 7 9 サイズ2000 サイズ3000 サイズ4000
  80. ただし CI は注意...... ‣PKCanvasView は Metal でレンダリングする • Machine 環境に依って、レンダリングされないことがあった

    • スペックを上げることで正しく動くことがあった • 直接的な原因はまだ特定できてません 8 0 https://developer.apple.com/jp/metal
  81. その他 Tips

  82. PKCanvasView は初回⽣成時重い ‣GPU (Metal) に依存しているため • タップしたタイミングで初回⽣成すると遅延が起きる • 事前に1度⽣成して⽴ち上げておく 8

    2
  83. Pencil や指の特殊なショートカットを作りたい ‣UIGestureRecognizer で Interaction を区別可能 • allowedTouchType で許可する ‣例えばペンシルでなぞる動作を拾うなら

    • allowedTouchType • [UITouch.TouchType.stylus] • minimumPressDuration / allowableMovement • ⼩さい値に / 広い値に 8 3 https://developer.apple.com/documentation/uikit/uigesturerecognizer/ 1 6 2 4 223 -allowedtouchtypes
  84. Pencil 2 の Double-Tap (消しゴムと切り替え) ‣UIPencilInteraction • Delegate 関数でカスタマイズできる 8

    4 https://developer.apple.com/documentation/uikit/pencil_interactions/handling_double_taps_from_apple_pencil let pencilInteraction = UIPencilInteraction() pencilInteraction.delegate = self view.addInteraction(pencilInteraction) func pencilInteractionDidTap(_ interaction: UIPencilInteraction) { if UIPencilInteraction.preferredTapAction == .switchPrevious { leftRingControl.switchToPreviousTool() } }
  85. 画像に描き込む場合 Light に固定する (といい?) ‣画像に描きこむとダークモードは...... • Drawingが黒と⽩で反転してしまう • Light モードを維持したい

    • systemColor は Light / Dark で少し違ったりも 8 5 https://developer.apple.com/design/human-interface-guidelines/foundations/color
  86. Human Interface Guideline にも ‣コンテンツへの描き込みは⾊を固定しましょう • ⾊合いが変わってしまうため 8 6 https://developer.apple.com/design/human-interface-guidelines/inputs/apple-pencil-and-scribble

    Help people draw on top of existing content. By default, the colors on your PencilKit canvas dynamically adjust to dark mode, so people can create content in either mode and the results will look great in both. However, when people draw on top of existing content like a PDF or a photo, you want to prevent the dynamic adjustment of colors so that the markup remains sharp and visible . PencilKit Custom Drawing - HIG -
  87. 具体的にどうするか? ‣UIUserInterfaceStyle を上書きする • PKCanvasView • overrideUserInterfaceStyle: UI の⾒た⽬ •

    PKToolPicker • overrideUserInterfaceStyle: UI の⾒た⽬ • colorUserInterfaceStyle: Drawing の選択⾊ • 黒で描いた線が⽩になる 8 7 外側だけ Dark も可能
  88. Tips 終わり!

  89. まとめ

  90. まとめ ‣PencilKit を拡張する • PencilKit の構造を UIScrollView の観点から観察 • 画像や独⾃

    Touch View を内部の View と⼲渉しないように合成する • PencilKit の編集モードを⽤意する • Preview‧Edit‧Highlight • リッチな機能を活かしつつ、追加拡張に成功 • 快適なスクラップ体験の実現! 9 0