介绍两种swiftUI实现画板的方法,演示的PaintDemo在这里
本博客请一定配合PaintDemo食用~Demo的PaintDemoApp需要读者手动切换两种demo。PaintDemo中介绍的两种画板实现方法都只实现了基础功能、包括调整画笔粗细、画笔颜色、保存画板内容到手机相册、清空画板等。
两种画板具体属性调整的方法不同但都不难理解。PaintDemo中大部分地方已经给出注释,相信读者自行阅读代码理解更快。也因此,下文仅指出两种画板实现中相对难理解,需要说明的地方。
PencilKit
PencilKit 是在2019年的 WWDC 上推出的。该框架是为了支持苹果的触控笔 Apple Pencil,并为开发者提供一个简单而强大的工具,用于在 iOS 和 iPadOS 上创建绘图和手写笔记应用程序。它提供了多种绘图工具、手写识别、橡皮擦工具以及手势和手写操作的支持。PencilKit 针对大规模手写和绘图场景进行了优化,与其他框架无缝集成,并且具有高性能和优化。自发布以来,PencilKit 已经成为开发者们创建涂鸦、手写输入和其他与笔迹相关的应用的主要选择之一。
简单来说PencilKit可以实现iPad自带画图工具的所有功能。Demo中只是简单实现了部分基础功能,代码都已经加上注释,有swiftUI基础应该都能看懂,就不多介绍啦。下面就部分细节进行说明。
Demo演示文件中的DrawingBoard就是自定义的Pencilkit的画板。常用参数和注释信息已在Demo中给出。makeUIView(context: Context)和updateUIView(_ uiView: UIViewType, context: Context)都是协议UIViewRepresentable的必须实现方法。需要说明的是makeUIView一经创建,绑定的canvas就无法更改,只能修改绑定的canvas的属性(也就是画笔粗细、颜色、工具)。
|
|
PKCanvasView提供了ink(.pencil、.pen、.marker)画图工具和eraser擦除工具,因为.pencil、.pen、.marker和eraser不是同一类。所以自定义的DrawingBoard需要绑定一个Bool值(Demo中绑定的是isDrawing)来切换ink和eraser两种工具。
|
|
同时由于Demo中的ink是个计算属性,跟颜色、粗细、ink类型都有关系可以实时检测改变,但是工具只是画图工具跟isDrawing没有联系。所以在updateUIView(_ uiView: UIViewType, context: Context)方法中来检测isDrawing的变化来切换ink和eraser。
Path
在SwiftUI框架中,Path 是一个用于绘制和操作矢量图形路径的类。 Path 提供了一个强大而灵活的 API,你可以通过添加直线、曲线、椭圆、矩形等基本图形元素来构造路径和操作矢量图形路径,从而实现各种自定义图形和动画效果。
通过Path来实现画板的思想是,先自定义每一段线段的颜色、粗细、样式。(Demo中没有设置画笔样式)
|
|
通过拖拽手势DragGesture的.onChanged和.onEnded可以轻松获取画图的路径数据,再通过addLine()连"点"成线。
|
|
同时记录下每次画画起点和终点index的位置,通过在lines数组中删掉对应的范围,即可实现画画回退效果。
|
|
需要注意的是,在PathDrawingDemo中我实现的屏幕截图方式跟PencilKitDemo的截图方式有些许不同,这种截图方式要求View必须有明确的bounds所以代码中通过.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 4/5)圈定了画板的长宽,读者可以自行对比参考。
|
|
终
个人角度来说,如果只需要实现画板的基础功能,那么首推PencilKit的方法,实现简单且好用。但是如果你需要实现复杂的画画效果,比如实现自定义的画笔路径或者想自定义实现多种画图工具,那么可以试试Path,Path虽难一点,麻烦一点但是无上限!读者可自行选择。