0
0
iOS Swiftmobile~20 mins

Canvas for drawing in iOS Swift - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Drawing Canvas
A screen where users can draw freehand lines with their finger on a blank canvas.
Target UI
-------------------------
| Drawing Canvas        |
|-----------------------|
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|-----------------------|
| Clear Button          |
-------------------------
A full screen white canvas area where user can draw lines with finger.
Lines should follow the finger movement smoothly.
A Clear button at the bottom to erase the drawing and start fresh.
Use UIKit and Swift.
Support portrait orientation.
Starter Code
iOS Swift
import UIKit

class DrawingView: UIView {
    // TODO: Add properties to track lines and touch points

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // TODO: Start a new line
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        // TODO: Add points to current line and redraw
    }

    override func draw(_ rect: CGRect) {
        // TODO: Draw all lines
    }

    func clear() {
        // TODO: Clear all lines and redraw
    }
}

class DrawingViewController: UIViewController {
    let drawingView = DrawingView()
    let clearButton = UIButton(type: .system)

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        drawingView.frame = view.bounds
        drawingView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(drawingView)

        clearButton.setTitle("Clear", for: .normal)
        clearButton.frame = CGRect(x: 20, y: view.bounds.height - 60, width: 100, height: 40)
        clearButton.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin]
        view.addSubview(clearButton)

        // TODO: Add target action for clear button
    }
Task 1
Task 2
Task 3
Task 4
Solution
iOS Swift
import UIKit

class DrawingView: UIView {
    private var lines: [[CGPoint]] = []

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let point = touches.first?.location(in: self) else { return }
        lines.append([point])
        setNeedsDisplay()
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let point = touches.first?.location(in: self), !lines.isEmpty else { return }
        lines[lines.count - 1].append(point)
        setNeedsDisplay()
    }

    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.setStrokeColor(UIColor.black.cgColor)
        context.setLineWidth(2)
        context.setLineCap(.round)

        for line in lines {
            guard let firstPoint = line.first else { continue }
            context.beginPath()
            context.move(to: firstPoint)
            for point in line.dropFirst() {
                context.addLine(to: point)
            }
            context.strokePath()
        }
    }

    func clear() {
        lines.removeAll()
        setNeedsDisplay()
    }
}

class DrawingViewController: UIViewController {
    let drawingView = DrawingView()
    let clearButton = UIButton(type: .system)

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        drawingView.frame = view.bounds
        drawingView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(drawingView)

        clearButton.setTitle("Clear", for: .normal)
        clearButton.frame = CGRect(x: 20, y: view.bounds.height - 60, width: 100, height: 40)
        clearButton.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin]
        view.addSubview(clearButton)

        clearButton.addTarget(self, action: #selector(clearDrawing), for: .touchUpInside)
    }

    @objc func clearDrawing() {
        drawingView.clear()
    }
}

We created a DrawingView subclass of UIView to handle touch events and drawing. It keeps an array of lines, where each line is an array of points. When the user touches the screen, a new line starts. As the finger moves, points are added to the current line. The draw(_:) method draws all lines with smooth black strokes.

The clear() method empties all lines and refreshes the view.

The DrawingViewController sets up the drawing view and a clear button. The button calls clear() on the drawing view to erase the canvas.

This approach uses UIKit touch handling and Core Graphics drawing to create a simple finger drawing canvas.

Final Result
Completed Screen
-------------------------
| Drawing Canvas        |
|-----------------------|
|                       |
|  *  *                 |
|   *   *               |
|    *    *             |
|     *     *           |
|      *      *         |
|       *       *       |
|        *        *     |
|         *         *   |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|-----------------------|
| Clear Button          |
-------------------------
User draws lines by dragging finger on the white canvas area.
Lines appear following finger movement smoothly.
Tapping Clear button erases all lines and resets the canvas.
Stretch Goal
Add an Undo button to remove the last drawn line.
💡 Hint
Keep track of lines in an array and remove the last one when Undo is tapped, then call setNeedsDisplay() to refresh.