본문 바로가기

iOS/SwiftUI

[SwiftUI] PencilKit을 사용해 캔버스 만들기

Swift의 PencilKit을 사용해 간단한 드로잉 앱을 만들어 보자 !!

 

가장 먼저 PencilKit을 임포트 해준다.

import SwiftUI
import PencilKit

 

UIKit의 PKCanvasView를 SwiftUI에서 사용하기

UIViewRepresentable를 사용하여 UIKit의 컴포넌트를 SwiftUI에서 사용할 수 있게 랩핑해준다.

struct CanvasView: UIViewRepresentable {
    let canvas: PKCanvasView
    let toolPicker: PKToolPicker
    
    func makeUIView(context: Context) -> PKCanvasView {
        canvas.isOpaque = false
        canvas.backgroundColor = .blue.withAlphaComponent(0.5)
        
        toolPicker.setVisible(true, forFirstResponder: canvas)
        toolPicker.addObserver(canvas)
        canvas.becomeFirstResponder()
        
        return canvas
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {}
}

 

SwiftUI에서 사용하기

앞서 만든 CanvasView를 불러와 사용하면 된다.

struct DrawingCanvas: View {
    let canvas = PKCanvasView()
    let toolPicker = PKToolPicker()
    
    var body: some View {
        CanvasView(canvas: canvas, toolPicker: toolPicker)
    }
}

 

+)

하단 toolPicker가 canvas를 가려서 아래 부분에 드로잉을 못하는 이슈가 있어서 scaleEffect를 사용하여 canvas의 크기를 줄여보았다.

struct DrawingCanvas: View {
    let canvas = PKCanvasView()
    let toolPicker = PKToolPicker()

    @State private var showsToolPicker: Bool = true

    var body: some View {
        NavigationView {
            CanvasView(canvas: canvas, toolPicker: toolPicker)
                .navigationTitle("Canvas")
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button(action: {
                            toolPickerToggle()
                        }) {
                            Text(showsToolPicker ? "Show" : "Draw")
                        }
                    }
                }
                .scaleEffect(showsToolPicker ? 0.75 : 1, anchor: .init(x: 0.5, y: 0.2))
        }
    }

    private func toolPickerToggle() {
        toolPicker.setVisible(!toolPicker.isVisible, forFirstResponder: canvas)
        withAnimation {
            showsToolPicker.toggle()
        }
    }
}

 

전체 코드

import SwiftUI
import PencilKit

struct DrawingCanvas: View {
    let canvas = PKCanvasView()
    let toolPicker = PKToolPicker()

    @State private var showsToolPicker: Bool = true

    var body: some View {
        NavigationView {
            CanvasView(canvas: canvas, toolPicker: toolPicker)
                .navigationTitle("Canvas")
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button(action: {
                            toolPickerToggle()
                        }) {
                            Text(showsToolPicker ? "Show" : "Draw")
                        }
                    }
                }
                .scaleEffect(showsToolPicker ? 0.75 : 1, anchor: .init(x: 0.5, y: 0.2))
        }
    }

    private func toolPickerToggle() {
        toolPicker.setVisible(!toolPicker.isVisible, forFirstResponder: canvas)
        withAnimation {
            showsToolPicker.toggle()
        }
    }
}

struct DrawingCanvas_Previews: PreviewProvider {
    static var previews: some View {
        DrawingCanvas()
    }
}

struct CanvasView: UIViewRepresentable {
    let canvas: PKCanvasView
    let toolPicker: PKToolPicker
    
    func makeUIView(context: Context) -> PKCanvasView {
        canvas.isOpaque = false
        canvas.backgroundColor = .blue.withAlphaComponent(0.5)
        
        toolPicker.setVisible(true, forFirstResponder: canvas)
        toolPicker.addObserver(canvas)
        canvas.becomeFirstResponder()
        
        return canvas
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {}
}