iOS/WWDC

Introducing PencilKit

HaningYa 2020. 9. 29. 15:42
728x90

[WWDC2019 Introducing Pencilkit]

 

Introducing PencilKit - WWDC 2019 - Videos - Apple Developer

Meet PencilKit, Apple's feature-rich drawing and annotation framework. With just a few lines of code, you can add a full drawing...

developer.apple.com

 

 

애플펜슬

  • 펜슬은 아이패드의 가장 특별한 기능이다.
  • 아이패드 미니부터 프로까지 사용할 수 있고 
  • 정밀한 작업이 필요한 곳 어디나 사용할 수 있다.

iOS13 에서 추가된 것

  • 낮은 지연(latency)
  • 새로운 팔레트 툴
  • 펜슬킷
  • Markup Everywhere

목차

  1. Great pencil experiences
  2. PencilKit
  3. Markup everywhere

Great Pencil experience

  • Precision을 통한 새로운 사용자 경험
  • 압력, 방위각, 고도를 통한 다양한 표현
  • 펜슬탭(2세대)을 통한 모드 변경

지원하는 3가지 종류의 펜슬과 스펙

from https://developer.apple.com/videos/play/wwdc2019/221/
from https://developer.apple.com/videos/play/wwdc2019/221/


How Pencil works

펜슬 팁의 위치가 240HZ 속도로 화면에 포인팅된다.

또한 펜슬의 방위각과 높이(기울기) 정보가 사용된다.

여기서 기울기는 펜슬 내부의 숨겨진 2번째 터치 포인트를 통해 계산된다.

마지막으로 Pressure를 사용한다.

방위각
고도와 2번째 히든 터치 포인트

 

주의할 점으로는

특징으로는 2번째 터치 포인트가 모호할 경우 방위각과 고도는 예측값이 사용될 수 있다.

방위각의 경우 펜슬이 수직인 경우에는 정확하지 않을 수 있다.

Force data가 터치 위치 데이터보다 딜레이 될 수 있다.

위의 경우를 적절히 처리하는게 쾌적한 사용자 환경을 제공하는데 키포인트가 된다.


2번째 터치포인트가 모호한 경우 예시

화면의 끝단에서 드로잉이 발생할 경우 2번째 숨겨진 터치포인트가 디스플레이상에 없어서 방위각과 고도가 제대로 계산이 될 수 없다.

이럴 경우 Back-fill을 통해서 이전 그려졌던 라인을 수정해주어야 한다.


압력 업데이트를 계속해서 update 해야하는 경우

펜슬이 아이패드에서 떼졌더라도 final Force value를 저장하고 있어야 한다.

문제는 다음 짧은 시간 내에 다음 Stroke 를 그릴때 Serial Queue를 사용해 하나의 stroke 로 간주되게 처리하는걸 추천한다.


레이턴시(지연율)

저 노란색 갭을 최대한 줄이는 것이 제일 중요하다. 방법으로는

  • Render with Metal : 일정한 렌더링 제공
  • Use predicted touches : 예측값 사용

드로잉 앱을 만들때 절대 하지 말아야될 것

  • Transparent Metal Layers
  • Overlay effects

UIEffectsView, Blurs, overlay 는 지양해야 한다.


펜슬 탭 제스쳐

콜백을 통해 탭 이벤트를 받고 적절히 모드를 선택할 수 있게 해야한다.


PencilKit (와우! 짝짝짝짝)

단 3줄로 펜슬 기능을 추가할 수 있다.


 

PKCanvasView

drawable region for your app
그림 그릴 수 있는 영역

PKDrawing

데이터 모델
Stroke 데이터 저장

PKToolPicker

툴 피커 UI를 스크린 아무곳에나 띄워줌

PKTools

  • PKInking Tool
  • PKEraser Tool
  • PKLassoTool

PKCanvasView

  • UIScrollView를 사용해 panning, zooming이 가능하다
  • drawing 이라는 데이터 모델을 사용가능하다.
  • tool을 통ㅎ interaction mode를 변경할 수 있다.
  • 변경사항에 대해 알려주는 Delegate 메소드가 존재한다.

PKDrawing

  • Seriaalizable to data
  • Generates Image
  • Can be appended or transformed
  • available on macOS

썸네일 생성코드 예제

값들이 value type 이기 때문에 background queue 에서 진행될 수 있다. drawing을 통해 이미지를 생성해 main frame에 업데이트 한다.


PencilKit tool

  • Pen
  • Marker
  • Pencil

CanvasView 를 ToolPicker 의 Observer로 설정하면 캔버스에 자동으로 설정된다.

따로 설정하려면 아래 코드처럼 구현하면 된다.

PKEraserTool

  • Vector: Object
  • Bitmap: Pixel

PKLassoTool

  • 특정 영역을 잘라서 복사하거나 옮기고 다른 앱에도 보낼 수 있다.

Ruler

  • Canvas 의 프로퍼티이다.

PKToolPicker

View가 아닌 Object로서 CanvasView와 별도로 동작한다. 

  • Keyboard와 유사하다. (view 계층 제일 상단에 위치, First Responder)

  • PKToolPicker를 윈도우에 올린다.
  • canvasView에 observer를 단다.
  • first responder를 정하고 true 로 값을 주면 Picker가 나타나게 된다.
  • false 일 경우 팔레트가 사라진다.
  • 마지막으로 canvasview를 first responder로 지정함으로 써 팔레트가 보여지게 한다.

Responder based Visibility

데모앱과 같이 시그니쳐 부분(우상단)에서 사용자에게 특정 펜과 색을 강제할 때 팔레트는 사라져야 한다. 이때는 

first responder를 시그니쳐 뷰로 바꾸면서 Tool Picker가 사라지게 된다.

시그니쳐 View를 Dismiss 할 경우 자동으로 first responder resign 이 되어 Tool Picker 가 다시 Visible 하게 된다.


Regular size vs Compact size

compact size class 의 경우 toolpicker는 하단에 고정되게 된다. 그래서 아래와 같이 구현해줘야 한다.

Undo, Redo Button 의 경우도

Regular Size는 Picker 내에 존재하지만 Compact size의 경우 뷰에 따로 추가해줘야 한다.


PKCanvasView Delegate callbacks

  • canvasViewDidBeginUsingTool: 펜슬이나 터치 이벤트가 감지되었을때
  • canvasViewDidEndUsingTool: 펜슬이나 터치 이벤트가 끝났을때, (하지만 drawing 은 아직 update 되지 않은 상태)
  • canvasViewDrawingDidChange: 이때 final finish drawing 을 얻을 수 있다. 이 콜백에서 이미지 저장하고 모델 업데이트하는 작업들을 할 수 있다.

  • 처음 비트맵으로 로딩되다가 canvasViewDidFinishRendering 이 콜백되었을때 완전히 로딩이 끝난 것이다.
  • Scrolling이나 Zooming 이후에도 해당 콜백이 호출된다.

손가락 드로잉과 스크롤링

  • allowsFingerDrawing 프로퍼티를 사용한다.
  • true일 경우 하나의 손가락 또는 펜슬로 그림을 그릴 수 있고 2손가락으로 스크롤을 한다.
  • false일 경우 펜슬로만 그림을 그릴 수 있고 한손가락으로 스크롤이 가능하다.

(아이폰의 경우 true 로 해줘야함, 펜슬 없기 때문에)


Drawing Over Content

  • opaque = false
  • background = .clear

기획상 다크모드를 지원하기 싫으면

light로 픽


Markup EveryWhere

canvasView 스크롤 있어도 스크린샷 전체적으로 된다. 

생략


정리

  • Drawing Engine을 직접 구현 해야할 때 주의할 것 (레이턴시, 방위각, 고도 등)
  • PencilKit API (Engine을 직접 구현하지 않고 쉽게 적용 가능)
  • PencilKit 이외의 API (펜슬 2세대의 더블탭, UIScreenShot)

 

728x90