通过本教程,你能学会在SwiftUI中调用PencilKit。
Jun-14-2020 11-02-51.gif
苹果iOS的Apple Pen的体验是在目前各品牌pad的手写笔中最好的。2019年,苹果官方为苹果笔的开发发布了PencilKit。不过PencilKit还是基于UIKit的,如何在SwiftUI中使用,本文来教你。
首先建立基本视图,其中注意PencilKit的主要对象有Canvas和PKDrawing,Canvas就是白板(也有叫画布的),PKDrawing就是在白板上画的图像了,它有函数可以转为UIImage或Data:
import SwiftUI
import PencilKit
struct ContentView: View {
@State private var showDrawView: Bool = false
// PencilKit相关的model应以PKDrawing为基本对象,需要导出时再用.image()或.dataRepresentation() 转换
@State var drawing = PKDrawing()
var body: some View {
VStack{
Image(uiImage: drawing.image(from: drawing.bounds, scale: 1) )
.resizable().frame(width:600, height: 800).border(Color.blue)
Button("画板"){
self.showDrawView.toggle()
}
.sheet(isPresented: self.$showDrawView) {
DrawView(isShown: self.$showDrawView, drawing: self.$drawing)
}
}
}
}
struct DrawView: View {
@Binding var isShown: Bool
@Binding var drawing: PKDrawing
var body: some View {
VStack{
HStack {
Spacer()
Button("Done"){
self.isShown.toggle()
}.padding(.trailing, 20)
}.padding(.top, 10)
Divider()
DrawCanvas(drawing: $drawing)
}
}
}
下面就是本文的主要技术点了: 如何从SwiftUI来调用UIKit中的Canvas,并保持主界面和Canvas之间的数据交互。Canvas具体的类名是PKCanvasView.
struct DrawCanvas: UIViewRepresentable {
@Binding var drawing : PKDrawing
func makeCoordinator() -> DrawCoordinator {
DrawCoordinator(self)
}
func makeUIView(context: Context) -> PKCanvasView {
let canvas = PKCanvasView()
canvas.isOpaque = false
canvas.backgroundColor = .clear
// 配置工具箱
let toolpicker = PKToolPicker.shared(for: UIApplication.shared.windows.first!)
toolpicker?.addObserver(canvas)
toolpicker?.setVisible(true, forFirstResponder: canvas)
canvas.becomeFirstResponder()
canvas.delegate = context.coordinator // 关键。设了才能得到输出!
// 来自父界面的输入
canvas.drawing = drawing
canvas.isScrollEnabled = true
return canvas
}
func updateUIView(_ canvas: PKCanvasView, context: Context) {
}
}
class DrawCoordinator : NSObject, PKCanvasViewDelegate {
var parent: DrawCanvas
init(_ uiView: DrawCanvas) {
self.parent = uiView
}
func canvasViewDrawingDidChange(_ drawView: PKCanvasView) {
// 输出到父界面
self.parent.drawing = drawView.drawing
}
}
网友评论