Build “SketchFX: Interactive Art Playground”

📖 Table of Contents

  1. Introduction
  2. Project Setup
  3. Understanding Core Graphics
  4. Creating a Custom Drawing View
  5. Handling Touch Events for Drawing
  6. Animating Strokes with Core Animation
  7. Adding Dynamic Brush Effects
  8. Implementing a Symmetry Mode
  9. Saving and Exporting Drawings
  10. Conclusion & Next Steps

🎬 Introduction

Welcome to this tutorial on Custom Drawing and Graphics with Core Graphics & Core Animation! In this guide, we’ll build “SketchFX: Interactive Art Playground”, an iPhone app that allows users to create beautiful sketches with animated effects. 🚀

By the end of this tutorial, you will:

✅ Understand Core Graphics (CG) for drawing custom shapes and lines.
✅ Use Core Animation (CA) to animate strokes dynamically.
✅ Build an interactive sketching app from scratch.

Let’s get started! 🎉

🛠 Project Setup

  1. Open Xcode and create a new project: a) Select iOS App → App b) Name it SketchFX c) Select Swift and UIKit as the interface
  2. Remove Main.storyboard and set up the UI in SceneDelegate.swift.

🖌 Understanding Core Graphics

Core Graphics (CGContext) is a powerful framework for drawing directly onto a view. It provides:
🎯 Path-based drawing (lines, shapes, curves)
🎯 Stroke and fill colors
🎯 Gradient and transparency effects

We’ll use it to create a custom canvas where users can draw with touch gestures.

🖼 Creating a Custom Drawing View

First, let’s create a custom UIView to handle the drawing logic.

🔹 Create a new Swift file: DrawingView.swift.
🔹 Subclass UIView and override draw(_:) to render strokes.

import UIKit

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

    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }

        context.setStrokeColor(UIColor.black.cgColor)
        context.setLineWidth(5)
        context.setLineCap(.round)

        for path in lines {
            context.addPath(path)
            context.strokePath()
        }
    }

    func addLine(path: CGPath) {
        lines.append(path)
        setNeedsDisplay() // Redraw the view
    }
}

✋ Handling Touch Events for Drawing

To allow users to draw, we need to capture touch gestures.

🔹 Update DrawingView.swift to track touch points:

private var currentPath = UIBezierPath()

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    currentPath = UIBezierPath()
    currentPath.lineWidth = 5
    if let touch = touches.first {
        currentPath.move(to: touch.location(in: self))
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        currentPath.addLine(to: touch.location(in: self))
        addLine(path: currentPath.cgPath)
    }
}

Now, we can draw smooth lines on our view! 🎨

🎞 Animating Strokes with Core Animation

Core Animation helps create smooth, fluid animations for strokes.

🔹 Add an animated stroke effect when drawing:

func animateStroke(path: CGPath) {
    let strokeLayer = CAShapeLayer()
    strokeLayer.path = path
    strokeLayer.strokeColor = UIColor.blue.cgColor
    strokeLayer.lineWidth = 5
    strokeLayer.fillColor = nil
    strokeLayer.lineCap = .round

    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.fromValue = 0
    animation.toValue = 1
    animation.duration = 1.0
    strokeLayer.add(animation, forKey: "drawAnimation")

    layer.addSublayer(strokeLayer)
}

Now, every stroke will have an animated effect! 🔥

🌈 Adding Dynamic Brush Effects

Let’s create a glowing brush using shadows and transparency.

func setupGlowingBrush() {
    let glowLayer = CAShapeLayer()
    glowLayer.shadowColor = UIColor.blue.cgColor
    glowLayer.shadowRadius = 10
    glowLayer.shadowOpacity = 0.8
    layer.addSublayer(glowLayer)
}

This gives our brush a cool neon glow! ✨

🪞 Implementing a Symmetry Mode

In Symmetry Mode, strokes are mirrored automatically.

🔹 Modify touchesMoved(_:) to draw on both sides:

if isSymmetryMode {
    let mirroredPoint = CGPoint(x: bounds.width - touchPoint.x, y: touchPoint.y)
    currentPath.addLine(to: mirroredPoint)
}

Now, strokes are mirrored, perfect for mandala-style drawings! 🌀

💾 Saving and Exporting Drawings

We can export drawings as images using UIGraphicsImageRenderer.

🔹 Add this function to DrawingView.swift:

func saveAsImage() -> UIImage {
    let renderer = UIGraphicsImageRenderer(bounds: bounds)
    return renderer.image { context in
        layer.render(in: context.cgContext)
    }
}

🔹 To save the drawing:

let image = drawingView.saveAsImage()
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)

This lets users save their sketches to the Photos app! 📸

🏁 Conclusion & Next Steps

🎉 Congratulations! You’ve built SketchFX, a powerful drawing app with:
✅ Custom strokes using Core Graphics
✅ Animated effects with Core Animation
✅ Dynamic brushes and glowing effects
✅ Symmetry mode for mandala art
✅ Saving and exporting to Photos

🚀 Next Steps

🔹 Add different brush styles (pencil, watercolor, spray paint).
🔹 Implement gesture-based UI controls for brush size and color.
🔹 Allow layers and undo functionality.

Thanks for following along! If you enjoyed this tutorial, share your artwork and tag me! 🎨🔥