Изучение разработки под iOS
Сделайте приложение для рисования на iOS в SwiftUI
Создайте полностью настраиваемое представление для использования в SwiftUI
Если вам нужно полностью настраиваемое представление, которое не имеет ни один из существующих компонентов UIView, вы должны создать свое собственное. Лучшим примером является создание вида чертежа, то есть вида, который, основываясь на вашем прикосновении, вы рисуете на нем.
С появлением Jetpack Compose и SwiftUI я изучил, как можно создать приложение для рисования в Jetpack Compose, как указано в статье ниже.
Я также подумал о том, чтобы изучить SwiftUI, чтобы узнать, как с его помощью можно создавать приложения для рисования. К сожалению, SwiftUI не имеет прямого доступа к CGContext в соответствии с этим StackOverflow. (Сообщите мне, если это неправда).
Но не волнуйтесь. Мы все еще можем обернуть традиционный UIView для использования в SwiftUI. Начнем с обычного UIView для нашего приложения для рисования.
Пользовательский UIView
Поскольку мы не можем превратить его в настраиваемый SwiftUI View, давайте воспользуемся обычным UIView, чтобы создать настраиваемый CanvasView для нашей цели рисования.
Сделайте индивидуальный вид для скаффолдера
Давайте создадим собственный UIView. Простой.
class CanvasView: UIView {}
Заменить функцию рисования
Теперь в CanvasView
переопределите функцию draw
и используйте UIGraphicsGenCurrentContext
, который вернет CGContext
, как очень полезный инструмент для рисования холста.
override func draw(_ rect: CGRect){ super.draw(rect) guard let context = UIGraphicsGetCurrentContext() else { return } // Use CGContext to draw here. context.setLineWidth(10) context.setLineCap(.round) context.strokePath() }
Отменить сенсорную функцию
Теперь в CanvasView
переопределите функцию захвата касания, чтобы мы могли соответственно получить координату. Давайте сделаем это для touchesBegin
, а также для touchesMoved
override func touchesBegan( _ touches: Set<UITouch>, with event: UIEvent?) { guard let point = touches.first?.location(in: self) else { return } // Capture the coordinate to start new line setNeedsDisplay() } override func touchesMoved( _ touches: Set<UITouch>, with event: UIEvent?) { guard let point = touches.first?.location(in: self) else { return } // Capture the coordinate to continue draw line setNeedsDisplay() }
Настроить класс пути
В отличие от Android, в iOS нет path
структуры, о которой я знаю. Итак, мы должны создать один для хранения захвата координат из функций touches
, чтобы функция draw
могла его получить.
struct Path { let type: PathType let point: CGPoint init(type: PathType, point: CGPoint) { self.type = type self.point = point } enum PathType { case move case line } }
Выше представлена простая структура Path
, которая хранит координату и указывает, является ли она move
(т. Е. Началом новой строки) или line
(т. Е. Непрерывным рисованием линии).
Имея это, теперь мы можем настроить координату из функций touch
для перехода к функции draw
.
class CanvasView: UIView { // An array of path to be drawn var paths = [Path]() override func draw(_ rect: CGRect){ super.draw(rect) guard let context = UIGraphicsGetCurrentContext() else { return } // Setup the path to be drawn paths.forEach { path in switch(path.type) { case .move: context.move(to: path.point) break case .line: context.addLine(to: path.point) break } } context.setLineWidth(10) context.setLineCap(.round) context.strokePath() } override func touchesBegan( _ touches: Set<UITouch>, with event: UIEvent?) { guard let point = touches.first?.location(in: self) else { return } // Capture the beginning point of line paths.append(Path(type: .move, point: point)) setNeedsDisplay() } override func touchesMoved( _ touches: Set<UITouch>, with event: UIEvent?) { guard let point = touches.first?.location(in: self) else { return } // Capture the line coordinates paths.append(Path(type: .line, point: point)) setNeedsDisplay() } }
С помощью приведенного выше кода теперь у нас есть холст для рисования UIView.
Оберните в SwiftUI View
Как показано в приведенном выше коде, CanvasView
на самом деле UIView
. Вам просто нужно создать UIViewRepresentable
(примечание: не обычный SwiftUI View
) и переопределить две функции, чтобы вернуть CanvasView
, а также установить backgroundColor.
struct CanvasViewWrapper : UIViewRepresentable { func makeUIView(context: Context) -> UIView { return CanvasView() } func updateUIView(_ uiView: UIView, context: Context) { uiView.backgroundColor = .white } }
Если вы обнаружите, что рисунок может попасть в безопасную зону, вы можете обратиться к этому StackOverflow.
Если вы предпочитаете быть в ViewController
Но если вы еще не вошли в SwiftUI и все еще используете ViewController, вы можете использовать следующее.
class CanvasViewController: UIViewController { let canvas = CanvasView() override func viewDidLoad() { super.viewDidLoad() view.addSubview(canvas) canvas.backgroundColor = .lightGray canvas.frame = view.frame } }
Теперь у вас есть приложение для рисования в обычном приложении ViewController или в приложении на основе SwiftUI.
Если вам понравился код, вы можете получить его отсюда.