iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
Mobile Development

從零開始學習 iOS系列 第 17

從零開始學習 iOS Day16 - Canvas

  • 分享至 

  • xImage
  •  

什麼是 Canvas

  • SwiftUI 的 繪圖容器,可用來繪製路徑、文字、圖片。
  • 適合做 自訂 UI 元件、資料視覺化、動畫
  • 本質上就是一個繪圖區域,類似 UIKit 的 draw(_:)

基本用法

struct CanvasExample: View {
    var body: some View {
        Canvas { context, size in
            // 繪製圓形
            let rect = CGRect(origin: .zero, size: size)
            context.fill(Path(ellipseIn: rect), with: .color(.blue))

            // 繪製文字
            context.draw(Text("Hello Canvas"), at: CGPoint(x: size.width/2, y: size.height/2))
        }
        .frame(width: 200, height: 200)
    }
}

https://github.com/jian-fu-hung/ithelp-2025/blob/main/image/Day16/%E6%88%AA%E5%9C%96%202025-10-01%20%E5%87%8C%E6%99%A81.10.02.png?raw=true

常見功能

Path:繪製幾何圖形

struct CanvasPathExample: View {
    var body: some View {
        Canvas { context, size in
            // 繪製矩形
            let rect = CGRect(x: 20, y: 20, width: 100, height: 100)
            context.fill(Path(rect), with: .color(.blue))

            // 繪製圓形
            let circle = CGRect(x: 150, y: 20, width: 100, height: 100)
            context.stroke(Path(ellipseIn: circle), with: .color(.red), lineWidth: 4)
        }
        .frame(height: 150)
    }
}

https://github.com/jian-fu-hung/ithelp-2025/blob/main/image/Day16/%E6%88%AA%E5%9C%96%202025-10-01%20%E5%87%8C%E6%99%A81.10.09.png?raw=true

  • fill:為填滿
  • stroke:為外框
  • x,y:表示中心點。

Text:在 Canvas 畫文字

struct CanvasTextExample: View {
    var body: some View {
        Canvas { context, size in
            let text = Text("Hello Canvas")
                .font(.title).foregroundColor(.purple)
            context.draw(text, at: CGPoint(x: size.width / 2, y: size.height / 2))
        }
        .frame(height: 100)
    }
}

https://github.com/jian-fu-hung/ithelp-2025/blob/main/image/Day16/%E6%88%AA%E5%9C%96%202025-10-01%20%E5%87%8C%E6%99%A81.10.16.png?raw=true


Image:繪製圖片

struct CanvasImageExample: View {
    var body: some View {
        Canvas { context, size in
            if let image = context.resolve(Image(systemName: "star.fill")) {
                context.draw(image, at: CGPoint(x: size.width/2, y: size.height/2))
            }
        }
        .frame(width: 150, height: 150)
    }
}

https://github.com/jian-fu-hung/ithelp-2025/blob/main/image/Day16/%E6%88%AA%E5%9C%96%202025-10-01%20%E5%87%8C%E6%99%A81.10.23.png?raw=true


Gradient:漸層繪製

struct CanvasGradientExample: View {
    var body: some View {
        Canvas { context, size in
            let rect = CGRect(origin: .zero, size: size)
            let gradient = Gradient(colors: [.blue, .green, .yellow])
            context.fill(Path(ellipseIn: rect),
                         with: .linearGradient(gradient,
                                               startPoint: .zero,
                                               endPoint: CGPoint(x: size.width, y: size.height)))
        }
        .frame(width: 200, height: 200)
    }
}

https://github.com/jian-fu-hung/ithelp-2025/blob/main/image/Day16/%E6%88%AA%E5%9C%96%202025-10-01%20%E5%87%8C%E6%99%A81.10.31.png?raw=true


Transform:旋轉、縮放

struct CanvasTransformExample: View {
    var body: some View {
        Canvas { context, size in
            let center = CGPoint(x: size.width/2, y: size.height/2)

            for i in 0..<12 {
                var path = Path()
                path.move(to: center)
                path.addLine(to: CGPoint(x: center.x, y: center.y - 80))

                // 建立旋轉矩陣
                let angle = Angle.degrees(Double(i) * 30)
                let transform = CGAffineTransform(translationX: center.x, y: center.y)
                    .rotated(by: CGFloat(angle.radians))
                    .translatedBy(x: -center.x, y: -center.y)

                context.stroke(path.applying(transform), with: .color(.orange), lineWidth: 2)
            }
        }
        .frame(width: 200, height: 200)
    }
}

https://github.com/jian-fu-hung/ithelp-2025/blob/main/image/Day16/%E6%88%AA%E5%9C%96%202025-10-01%20%E5%87%8C%E6%99%A81.10.38.png?raw=true

每條線從中心出發,旋轉後形成鐘錶刻度效果。


今日小結

  • Canvas 可以繪製 幾何圖形、文字、圖片、漸層,並支援 旋轉、縮放

明天會介紹 SwiftUI 與 Storyboard 的互動使用


上一篇
從零開始學習 iOS Day15 - 動畫
下一篇
從零開始學習 iOS Day17 - MVVM架構
系列文
從零開始學習 iOS24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言