Symbol Draw On
An SF Symbol that draws itself on and off, stroke by stroke.

- Modern
- iOS 26.0+
- beginner
- Origin
- Original work
- Found by
- sf symbols · symbol effect · draw on · draw off · stroke · handwriting · icon animation · símbolos · efecto de símbolo · dibujar · trazo · animación de icono · escritura a mano
Description
Section titled “Description”An SF Symbol that draws itself on and off, stroke by stroke.
Only symbols with Draw annotations trace their strokes. Others fall back to a simpler appearance. With Reduce Motion on, the symbol fades.
@available(iOS 26, *)struct SymbolDrawOnDemo: View { @State private var isDrawn = true @ScaledMetric(relativeTo: .largeTitle) private var cellSize = 104.0 @Environment(\.accessibilityReduceMotion) private var reduceMotion
private let symbols = ["signature", "scribble", "wind", "sun.max", "cloud.rain", "checkmark.circle"]
var body: some View { ZStack { LinearGradient(colors: [.indigo, .black], startPoint: .top, endPoint: .bottom) .ignoresSafeArea()
LazyVGrid(columns: [GridItem(.adaptive(minimum: cellSize))], spacing: 28) { ForEach(symbols, id: \.self) { symbol in SymbolDrawOn(systemName: symbol, isDrawn: isDrawn) .font(.largeTitle.weight(.medium)) .imageScale(.large) .foregroundStyle(.white) .frame(height: cellSize) } } .padding(24) } .task { guard !reduceMotion else { return } while !Task.isCancelled { try? await Task.sleep(for: .seconds(isDrawn ? 1.8 : 1.3)) withAnimation { isDrawn.toggle() } } } }}
@available(iOS 26, *)API reference
Section titled “API reference”| Parameter | Type | Default |
|---|---|---|
systemName | String | Required |
isDrawn | Bool | Required |
label | LocalizedStringKey? | nil |
Copy this code into your project, or download the file.
// SPDX-License-Identifier: MIT// Copyright (c) 2026 Oscar Canton and SwiftUI Blocks contributors
import SwiftUI
/// An SF Symbol that draws itself on and off, stroke by stroke.////// Only symbols with Draw annotations trace their strokes. Others fall back to a simpler/// appearance. With Reduce Motion on, the symbol fades.@available(iOS 26, *)struct SymbolDrawOn: View { let systemName: String var isDrawn: Bool var label: LocalizedStringKey?
@Environment(\.accessibilityReduceMotion) private var reduceMotion
var body: some View { Image(systemName: systemName) .symbolEffect(.drawOn.byLayer, isActive: !isDrawn) .symbolEffect(.drawOff.byLayer, isActive: !isDrawn) .symbolEffectsRemoved(reduceMotion) .opacity(reduceMotion && !isDrawn ? 0 : 1) .accessibilityRepresentation { if let label { Image(systemName: systemName).accessibilityLabel(label) } } }}
// MARK: - Demo
@available(iOS 26, *)struct SymbolDrawOnDemo: View { @State private var isDrawn = true @ScaledMetric(relativeTo: .largeTitle) private var cellSize = 104.0 @Environment(\.accessibilityReduceMotion) private var reduceMotion
private let symbols = ["signature", "scribble", "wind", "sun.max", "cloud.rain", "checkmark.circle"]
var body: some View { ZStack { LinearGradient(colors: [.indigo, .black], startPoint: .top, endPoint: .bottom) .ignoresSafeArea()
LazyVGrid(columns: [GridItem(.adaptive(minimum: cellSize))], spacing: 28) { ForEach(symbols, id: \.self) { symbol in SymbolDrawOn(systemName: symbol, isDrawn: isDrawn) .font(.largeTitle.weight(.medium)) .imageScale(.large) .foregroundStyle(.white) .frame(height: cellSize) } } .padding(24) } .task { guard !reduceMotion else { return } while !Task.isCancelled { try? await Task.sleep(for: .seconds(isDrawn ? 1.8 : 1.3)) withAnimation { isDrawn.toggle() } } } }}
@available(iOS 26, *)#Preview { SymbolDrawOnDemo()}