Slide 1

Slide 1 text

E ff ective PencilKit 新聞スクラップ体験の実現 Go Takagi 20 22 / 09 / 12 iOSDC JAPAN 2 022 Day 2 #Track B 13 : 0 0 〜

Slide 2

Slide 2 text

Me ( Go Takagi ) ‣ID • shimastripe / shimastriper ‣Work • 株式会社 ⽇本経済新聞社 ‣ iOS 紙⾯ビューアーアプリ の開発を担当 • iOSDC NOC チーム ‣Like • 柴⽝が⼤好きです! 2 2年ぶりにカムバックです!

Slide 3

Slide 3 text

Keynote ‣PencilKit を拡張する • Example より更に先のユースケースへ対応 ‣Points • PencilKit で Preview / Edit できる画⾯ • 独⾃のペンツールを統合 • テキストハイライト機能 • ツールパレット • Test‧その他Tips 3

Slide 4

Slide 4 text

Introduction

Slide 5

Slide 5 text

紙⾯ビューアー: 新聞紙⾯画像に特化 ‣紙⾯画像形式で読める • 縦 (+ 横) 書き 両対応 • iPad 利⽤者多い • オフライン動作 • Wi-Fi で夜間に⾃動DL • iOSDC 2 0 2 0 もぜひ 🙏 5 AppStore ページより

Slide 6

Slide 6 text

紙⾯画像に描き込みを⾏いたい! 6 Zoom や Scroll ができる

Slide 7

Slide 7 text

紙⾯画像への描き込み => スクラップ体験 ‣デジタルでも実現したい • 紙に描いて残す体験を再現 ‣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

Slide 8

Slide 8 text

Apple Pencil で描けるメモ機能をリリース 8 https://www.youtube.com/watch?v=JwltoOq_JeU

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

描いたメモは保存(ロック)し、表⽰+⾮表⽰できる ‣編集モードが切り替えできる • Preview / Edit • Preview 中は Scroll / Zoom のみ可能 ‣描き込み表⽰が切り替えできる • 描き込み ON / OFF ‣保存したデータはSyncされる • 端末をまたいで描き込みメモが残せる 1 0

Slide 11

Slide 11 text

段落も考慮した本⽂のハイライトマーカー ‣独⾃ペンツールを統合 • HighlightKit を内製 • Canvas に共存して利⽤可能に 1 1

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

PencilKit

Slide 14

Slide 14 text

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)

Slide 15

Slide 15 text

Apple Pencil ‣低レイテンシ • 1秒間に240回スキャニングして情報を送る (240 Hz) • 描いたイメージとディスプレイへの描画遅れが極⼩ ‣たくさんの情報 • altitude (⾼度) / pressure (圧⼒) / azimuth (⽅位) ‣Scribble による⼿書き認識 (iOS 1 4 +) • タブレットの⼊⼒⽅法に新しい体験 1 5

Slide 16

Slide 16 text

PencilKit のここが凄い! ‣Apple Pencil 体験を容易に導⼊できる • OS 標準の Canvas が再現できる ‣低レイテンシ • Pencil から送られる⼊⼒を素早く画⾯に反映 • Metal の API を⽤いたレンダリング ‣描画したものが構造的なデータで表されている • 永続化して再編集可能 ‣Image形式で出⼒可能 • サムネイル画像が⽣成できる 1 6 WWDC: 1 9 Introducing PencilKit

Slide 17

Slide 17 text

独⾃実装する場合 (≠ 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

Slide 18

Slide 18 text

Example App: Drawing with PencilKit ‣⼀通りまとまってる • Canvas を表⽰する • 描き込み領域の⾃動拡張⽅法 • ペンのツールパレットを表⽰する • Undo / Redo • 署名 (Signature) • サムネイル⽣成 • PKDrawing (描き込みデータ) の永続化 1 8 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit ⼀通りアプリが作れそう!

Slide 19

Slide 19 text

Example 以上のことできなくない......?🤔 ‣⼀通りリッチに機能はあるけど • Example 以上のものを作れない • 絶妙にやりたいことに⼿が届かない 1 9 と思ったのは⾃分だけじゃない......はず??

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

できる拡張を探して実現していく ‣View の構造に着⽬ • PencilKit の性質から構造を推測 • 可能そうな拡張⽅法を試していく ‣PencilKit の資産を活かしてアプリが作れる • ユースケースを満たしつつ、再実装を避ける 2 1

Slide 22

Slide 22 text

Example を通して PencilKit を紹介

Slide 23

Slide 23 text

⼤まかな構成 ‣PKCanvasView • キャンバスとなる UIScrollView ‣PKToolPicker • ペンツール (ペン‧鉛筆‧消しゴム‧定規) • PKTool: PKInkingTool / PKEraserTool / PKLassoTool ‣PKDrawing • 描き込みデータを表す構造体‧ストロークのパスも取れる • Codable に対応、永続化‧復元が容易にできる • UIImage への変換も可能 2 3 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit

Slide 24

Slide 24 text

拾えるイベント ‣PKCanvasViewDelegate • UIScrollViewDelegate • PKDrawing 周りの変更イベント • Tool を使って描き始め / 終わり ‣PKToolPickerObserver • ToolPicker の選択 / 移動 / 表⽰ 2 4 ダークモードだと⾊が反転 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit

Slide 25

Slide 25 text

Example から学べること ‣⼀連の描き込み体験は作れる • 描き込みキャンバスの実現 • Drawing の変更時に Undo / Redo を適宜更新 • 余⽩が狭くなったらキャンバスサイズの更新 • リアルタイムで更新して無限キャンバスも • Canvas をカスタマイズする要素は⾒当たらない • Canvasにイメージを⼊れる⽅法はわからない...... ‣永続化‧画像化 • PKDrawing を Data に変換して保存 • UIImage を書き出して保存 2 5

Slide 26

Slide 26 text

拡張に取り組んでいく

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

画像へ描き込みを実現したい

Slide 29

Slide 29 text

UIImageView in UIScrollView ‣⼤きいコンテンツを部分的に表⽰するカメラ(View) • ContentView: ScrollView の subview • Zoomやスクロール、余⽩をカスタマイズできる 2 9 https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html

Slide 30

Slide 30 text

既存紙⾯画像ページ: ⼀般的なImageViewer ‣UIScrollView の中に Image • ズーム‧スクロールができる • 画像は3段階の画質をサポート ‣カスタマイズ • ダブルタップでカスタムジェスチャー • 横書きモードの表⽰‧保存‧共有 • iPad SplitView 3 0 UIScrollView

Slide 31

Slide 31 text

ImageViewer に描き込みを⾏いたい ‣ImageViewer に PKCanvasView ( UIScrollView ) を重ねる • 重ねて同時に操作してみる? 3 1 UIScrollView PKCanvasView

Slide 32

Slide 32 text

失敗......というか断念

Slide 33

Slide 33 text

2枚の同期が難しい ‣Zoom の調整 • ContentView 同⼠のサイズが違うと、 Zoom する⼤きさや位置が変わる • iPhone, iPad, SplitView でも対応しないといけない ‣PencilKit 側の描画が遅れる • 別の View 越しにイベントを伝えているため? • ⽬で⾒てアウトな品質に ‣何より管理が複雑 • 機能追加するたびに UIScrollView が増えたりしたら......⽅針を変える 3 3

Slide 34

Slide 34 text

PKCanvasView = UIScrollView ‣UIScrollView として観察してみる • ContentView = 描き込み領域? • 発⾒できれば • ContentView に Image を Insert できないか • 実現できれば ScrollView 1 枚化ができそう 3 4 https://developer.apple.com/documentation/pencilkit/drawing_with_pencilkit

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

(参考までに) UIScrollView の場合は ‣構造が似ている • UIImageView ( ContentView ) • _UIScrollViewScrollIndicator * 2 • スクロールインジケーター 3 7

Slide 38

Slide 38 text

ContentView? に View を⼊れてみる ‣PKCanvasView • backgroundColor = .systemRed ‣UIImageView を⼊れてみる • ContentView に Insert 3 8

Slide 39

Slide 39 text

Drawing 中 背景⾊になってしまう ‣PKCanvasView • PKCanvasAttachment の tintColor と連携? • backgroundColor = .clear にしてみると....... ‣UIImageView と 背景 UIView • ContentView に Insert • 必要あれば背景 View を追加で Insert 3 9

Slide 40

Slide 40 text

画像の上に描き込みができる! ‣ScrollやZoomも滑らか!ズレない! • 描き込み領域は • canvasView.contentSize を設定して調整可能 • ImageSize から必要な余⽩を計算し、contentSize にする ‣3種類の画質の画像と合成 • PKDrawing と画像を分けて保存 • 画像サイズに応じて倍率を計算し、Drawingと重ねる 4 0

Slide 41

Slide 41 text

(再掲) 既存紙⾯画像ページ: ⼀般的なImageViewer ‣UIScrollView の中に Image • ズーム‧スクロールができる • 画像は3段階の画質をサポート ‣カスタマイズ • ダブルタップでカスタムジェスチャー • 横書きモードの表⽰‧保存‧共有 • iPad SplitView 4 1 UIScrollView

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

4 3 PencilKit! UIScrollView PKCanvasView

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

Preview / Edit の切り替え

Slide 47

Slide 47 text

Canvas を Preview / Edit 切り替えする ‣メモアプリ • Preview は1本指でスクロール • Edit は、1本指で描画、2本でスクロール ‣描き込みだけ OFF にするには canvasView.isUserInteractionEnabled = false • 全ての Gesture が動かなくなる....... canvasView.drawingGestureRecognizer.isEnabled • Drawing に関する操作だけ Disabled にできる 4 7 Preview Edit ❌ ⭕

Slide 48

Slide 48 text

4 8 PencilKit! UIScrollView PKCanvasView

Slide 49

Slide 49 text

4 9 Draw ON Draw OFF Pencil で描ける! スクロール操作のみできる Edit Preview UIScrollView PKCanvasView の描き込みモードを切り替える

Slide 50

Slide 50 text

5 0 Pencil で描ける! スクロール操作のみできる ダブルタップや保存‧共有機能を移植する! Edit Preview Draw ON Draw OFF

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

独⾃マーカーの実装 ‣テキストハイライト • 本⽂に沿って • 滑らかに綺麗に 5 4 PencilKitのマーカーでは 滲んで⾒えてしまう

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

独⾃マーカー⽤の View も ContentView に⼊れる ‣PKCanvasView を UIScrollView として更に使う! • ContentView • CanvasBackgroundView • ImageView • PKCanvasAttachmentView • HighlightView • PKTiledCanvasView (hidden) • ...etc. 5 7 台紙となる背景 紙⾯画像 ⼿描き領域 独⾃マーカー

Slide 58

Slide 58 text

5 8 Pencil で描ける! スクロール操作のみできる Edit Preview Draw ON Draw OFF Highlight Draw OFF Draw ON 独⾃マーカー!

Slide 59

Slide 59 text

Highlightの仕組み ‣始点と終点をキャプチャ • 間にある番号をすべて塗る 5 9 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ㉑ ㉒ ㉓ ㉔ ㉕ ㉖ ㉗ ㉘ ㉙ ㉚ ㉛ ㉜ ㉝ ㉞ ㉟ ㊱ ㊲ ㊳ ㊴ ㊵ ㊶ ㊷ ㊸ ㊹ ㊺ ㊻ ㊼ ㊽ ㊾ ㊿

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

新聞画像のテキスト領域の抽出 ‣既存の OCR の精度で限界 • OCRとは画像から⽂字の領域と内容を抽出する技術のこと • 新聞特有の性質と相性が悪かった • 可変幅フォント • 組み⽂字 • 段落順序がバラバラ • (直感的でない) • 技術的制約で⽂字埋め込みのPDFの使⽤は困難 6 2

Slide 63

Slide 63 text

新聞縦書き向け⽂字座標抽出ロジックを開発 6 3 Google Cloud Vision API 開発した⼿法 ※ 2022年04⽉時点

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

PKToolPicker

Slide 67

Slide 67 text

PKToolPicker ‣メモの Tool パレットを利⽤可能! • iPhone / iPad で機能差があることに注意 • iPhone は「Undo‧Redo」がついていない • 3本指で左から右にスワイプすると同じジェスチャーがあります 6 7

Slide 68

Slide 68 text

Phone モードでは個別に⽤意を検討 ‣HIG で指摘されていました 6 8 https://developer.apple.com/design/human-interface-guidelines/inputs/apple-pencil-and-scribble

Slide 69

Slide 69 text

ほとんどカスタムできない ‣⼀部の設定の ON / OFF のみ • 定規を表⽰するか • 指で描画を許可する設定を出すかどうか ‣CustomTool の追加‧削除 • できない、特定のTool だけ表⽰は無理 6 9 マーカーだけ独⾃実装のものにしたいが...

Slide 70

Slide 70 text

ToolPicker を完全に⾃作すればやれる....... ‣標準 ToolPicker を外から操作する • PKCanvasView.tool / PKToolPicker.selectedTool を上書き ‣独⾃ツールも⼊ったツールパレットを作りたい場合 • 完全⾃作して UI を作る • 各種ボタンで Gesture をうまく切り替える • PKCanvasView の描き込み Gesture を ON/OFF • Custom Tool の Gesture を ON/OFF 7 0

Slide 71

Slide 71 text

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) }), ])

Slide 72

Slide 72 text

PKToolPicker のカスタマイズ情報 ‣UserDefaults に保存 • ユーザーが意図的に変えたか判断できる • 複数プリセットも⽤意可能 • PKToolPicker の stateAutosaveName を上書きする 7 2

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

Testing

Slide 75

Slide 75 text

拡張した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")

Slide 76

Slide 76 text

他にもカスタマイズした設定があれば Assert ‣ペンツールの設定 • PKDrawing / PKToolPicker は Equatable に準拠 • AssertionTest が書きやすい • 初期選択ツールのチェック • ユーザー選択後はそちらが維持されるチェック 7 6

Slide 77

Slide 77 text

PKDrawingと画像の合成テスト ‣合成がズレていないかテストしたい • 描き込みデータを複数サイズの画像とマージ • 3段階の画質 • iPhone / iPad の⾒た⽬ 7 7 3段階のサイズ と合体する

Slide 78

Slide 78 text

ビジュアルリグレッションテスト ‣ 視覚の回帰テスト • View 単位でデグレを検知 • スクリーンショットの Di ff を⽤いた差分検知 など • uber/ios-snapshot-test-case や pointfreeco/swift-snapshot-testing が有名 7 8 A A' A'

Slide 79

Slide 79 text

PKDrawing は Codable に対応 ‣特定の描き込み状態を⽤意に再現可能 • Data 型から復元して、Canvasに適⽤した画⾯を⽐較 • 同じに⾒えて紙⾯画像は 3 種類別サイズ 7 9 サイズ2000 サイズ3000 サイズ4000

Slide 80

Slide 80 text

ただし CI は注意...... ‣PKCanvasView は Metal でレンダリングする • Machine 環境に依って、レンダリングされないことがあった • スペックを上げることで正しく動くことがあった • 直接的な原因はまだ特定できてません 8 0 https://developer.apple.com/jp/metal

Slide 81

Slide 81 text

その他 Tips

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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() } }

Slide 85

Slide 85 text

画像に描き込む場合 Light に固定する (といい?) ‣画像に描きこむとダークモードは...... • Drawingが黒と⽩で反転してしまう • Light モードを維持したい • systemColor は Light / Dark で少し違ったりも 8 5 https://developer.apple.com/design/human-interface-guidelines/foundations/color

Slide 86

Slide 86 text

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 -

Slide 87

Slide 87 text

具体的にどうするか? ‣UIUserInterfaceStyle を上書きする • PKCanvasView • overrideUserInterfaceStyle: UI の⾒た⽬ • PKToolPicker • overrideUserInterfaceStyle: UI の⾒た⽬ • colorUserInterfaceStyle: Drawing の選択⾊ • 黒で描いた線が⽩になる 8 7 外側だけ Dark も可能

Slide 88

Slide 88 text

Tips 終わり!

Slide 89

Slide 89 text

まとめ

Slide 90

Slide 90 text

まとめ ‣PencilKit を拡張する • PencilKit の構造を UIScrollView の観点から観察 • 画像や独⾃ Touch View を内部の View と⼲渉しないように合成する • PencilKit の編集モードを⽤意する • Preview‧Edit‧Highlight • リッチな機能を活かしつつ、追加拡張に成功 • 快適なスクラップ体験の実現! 9 0