【簡単】PencilKitを使ってお絵かきアプリを作る方法

5 min

こんにちは、たいちです(@taichi_swift_)

たかし

たかし

iPadとApplePencilを買ったから、自分専用のお絵かきアプリを作りたい!でもどうやってつくるんだろ?

このお悩みを解決します。

本記事の内容
  • SwiftUIとPencilKitを使い、オリジナルのお絵かきアプリを作る方法

本記事の読者
  • iPadとPencilKitを使って、オリジナルのお絵かきアプリを作りたい人
本記事を読むメリット
  • PencilKitのビューをSwiftUIで使う方法がわかる

PencilKitを使ったアプリの完成形

今回作るアプリは非常にシンプルで、

みなさんは、PencilKitでアプリを作ったことはありますか?
今回は、WWDC2019で発表されたPencilKitを使用して表現力豊かで待ち時間の少ない描画を行う方法をご紹介します。

https://developer.apple.com/documentation/pencilkit

PencilKitのApple Documantationによると、UIKitと組み合わせる方法はコードを3行追加するだけと謳われていますね。

それはUIKitを使う前提で、SwiftUIでPencilKitのキャンバスを使う方法がなかなか見つかりません。

そこで、UIViewRepresentableでUIKitのビューをSwiftUIで使えるようにしてみました。

記事の最後に本記事で作ったアプリのソースコードも公開しています!

たいち

たいち

PencilKitを使ったお絵かきアプリの作り方

【環境】
Xcode11.5
Swift5.2
iPadアプリとして作ります。

iPhoneアプリとして作ってもOK!

たいち

たいち

Xcodeでプロジェクトを作る

まずは「shift + ⌘ + N」か、File → New → Project…で新しいXcodeプロジェクトを作ります。

「iOS」の「Single View App」を選び、Nextをクリックします。

  • Product Name: 「PencilDrawing」
  • Language: Swift
  • User Interface: SwiftUI

プロジェクトを新しく作る方法はこの記事のほうが詳しく解説してるよ!

たいち

たいち

新しいアプリを作成することができました。

新しいファイルを追加する

Xcodeの画面左側にある黄色いフォルダを右クリックして、New File…をクリックします。

(慣れていれば⌘ + Nが楽です)

ファイルのテンプレートは「SwiftUI View」

名前は「CanvasView.swift」としておきます。

PencilKitを使うためにimportする

import SwiftUIの上か下にimport PencilKitを追加します。
Appleが用意したフレームワークをファイル内で使うときは必ず書きましょう。

import SwiftUI
import PencilKit //必ず追加する

UIViewRepresentableのビューを宣言する

SwiftUIの機能ではPencilKit専用のViewをそのまま使えないので、UIViewRepresentableを使います。

struct CanvasView: View {
//...
}

  ↓書き換える

struct CanvasView: UIViewRepresentable {
//...
}

CanvasViewの中身を変更していきます。

var body: some View {
Text("Hello World!")
}

  ↓書き換える

@Binding var canvasView: PKCanvasView

func makeUIView(context: Context) -> PKCanvasView {
    self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
    return canvasView
}

func updateUIView(_ uiView: PKCanvasView, context: Context) {
}


import SwiftUI
import PencilKit //追加

struct ContentView: View {
    @State private var canvasView: PKCanvasView = PKCanvasView() //追加
    var body: some View {
        CanvasView(canvasView: self.$canvasView) //変更
    }
}

ContentViewの中身をCanvasView()に入れ替えて実行してみましょう。

↓ iPadで実行してみた動画

現時点では指でのタッチと、Apple Pencilでのタッチ両方を認識しています。

Apple Pencilのタッチだけを認識する方法

Apple Pencilのタッチだけを認識する方法をご紹介します。

実はとても簡単で、PKCanvasView()のallowsFingerDrawingというプロパティにfalseを代入するだけです。

コードで見ていきましょう。

ContentViewの方で操作する場合

struct ContentView: View {
    var body: some View {
        CanvasView()
            .onAppear {//ここから
                self.canvasView.allowsFingerDrawing = false
        }//ここまで追加
    }
}

CanvasViewの方で操作する場合

///CanvasView()
func makeUIView(context: Context) -> PKCanvasView {
    self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
    self.canvasView.allowsFingerDrawing = false//追加
    return canvasView
}

これだけです。指でのタッチは受け付けなくなりました。

さらに、メモアプリやスクショを撮ったときによくみるペンの色や太さを変更する部品も追加してみましょう。

一応、PKToolPicker: ツールピッカーという名前がついてます

たいち

たいち

PKToolPickerをキャンバスに追加する方法

CanvasViewにコードを追加します。

func makeUIView(context: Context) -> PKCanvasView {
    self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
    //ここから
    if let window = UIApplication.shared.windows.first {
        if let toolPicker = PKToolPicker.shared(for: window) {
            toolPicker.addObserver(canvasView)
            toolPicker.setVisible(true, forFirstResponder: canvasView)
            canvasView.becomeFirstResponder()
        }
    }
    //ここまで追加
    return canvasView
}
    
func updateUIView(_ uiView: PKCanvasView, context: Context) {
}

ここで実行してみましょう。

指とApple Pencilで自由に動かせるツールピッカーを追加できました。

ペンの設定(色・太さなど)や消しゴム、投げ縄ツール、定規などがこれだけで使えるようになります。

まとめ・ソースコード

今回はメモアプリ等でも使われているPencilKitをSwiftUIとコラボさせる方法についてご紹介しました。

実は他にも機能があって、Undo, Redo(取り消し、やり直し)機能や、描画をまとめて削除する方法、UIImageに変換する方法など様々なことができます。

みなさんでいろいろ試してみてくださいね!

【ソースコード】

こちらをコピーしてあなたのプロジェクトに貼り付けるだけです。

import SwiftUI
import PencilKit

struct ContentView: View {
    @State private var canvasView: PKCanvasView = PKCanvasView()
    var body: some View {
        CanvasView(canvasView: self.$canvasView)
    }
}

struct CanvasView: UIViewRepresentable {
    @Binding var canvasView: PKCanvasView
    
    func makeUIView(context: Context) -> PKCanvasView {
        self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
        if let window = UIApplication.shared.windows.first {
            if let toolPicker = PKToolPicker.shared(for: window) {
                toolPicker.addObserver(canvasView)
                toolPicker.setVisible(true, forFirstResponder: canvasView)
                canvasView.becomeFirstResponder()
            }
        }
        return canvasView
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {
    }
}

最後まで読んでくれてありがとうございます!

こちらから他のSwiftの記事を読むことができます!

iPadに指で文字書くの難しかった…笑

たいち

たいち

関連記事

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です