The Util Designer
SwiftUI 學習 StrokeStyle
Xcode 14.0, swift 5.7, iOS 16.0
2022-09-22
SwiftUI 里可以使用Shape來畫自定議圖形,而在Shape中可以StrokeStyle來控制不同的線條樣式。
1. 為了演示不同的StrokeStyle,先自定議一個圖形:
struct CustomShape : Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            path.move(to: CGPoint(x: 50, y: 50))
            path.addLine(to: CGPoint(x: 100, y: 100))
            path.addLine(to: CGPoint(x: 150, y: 50))
            path.addLine(to: CGPoint(x: 200, y: 200))
        }
    }
}

struct StrokeStyleExample: View {
    var body: some View {
        CustomShape().stroke(.green, lineWidth: 20)
    }
}
2. 先使用StrokeStyle的lineWith 線的寬度:
struct StrokeStyleExample: View {
    var body: some View {
        let strokeStyle = StrokeStyle(lineWidth: 20)
        CustomShape().stroke(.green, style: strokeStyle)
    }
}
3. 設置lineCap來設置線段兩頭樣式,可以使用butt / round / squre:
struct HorizontalLine : Shape {
    let y : Double
    
    func path(in rect: CGRect) -> Path {
        Path { path in
            path.move(to: CGPoint(x: 0, y: y))
            path.addLine(to: CGPoint(x: rect.width, y: y))
        }
    }
}
struct StrokeStyleExample: View {
    var body: some View {
        let strokeStyle = StrokeStyle(lineWidth: 20, lineCap: .square)
        GeometryReader { proxy in
            HorizontalLine(y: 50.0).stroke(.black, lineWidth: 1)
            CustomShape().stroke(.green, style: strokeStyle)
            HorizontalLine(y: 200.0).stroke(.black, lineWidth: 1)
        }
    }
}
.butt
.round
.square
4. 設置 lineJoin 來設置線段的連結點樣式,可以使用round / bevel / miter:
struct StrokeStyleExample: View {
    var body: some View {
        let strokeStyle = StrokeStyle(lineWidth: 20, lineCap: .butt, lineJoin: .round)
        GeometryReader { proxy in
            HorizontalLine(y: 50.0).stroke(.black, lineWidth: 1)
            CustomShape().stroke(.green, style: strokeStyle)
            HorizontalLine(y: 200.0).stroke(.black, lineWidth: 1)
        }
    }
}
.round
.bevel
.miter
5. 設置 dash來制作線段的虛線樣式,dash是一個每個間隔的長度數組,就是有線,無線不間段來畫線,第一個是間隔為10的虛線,第二個是間隔為20的虛線,第三個比較複雜,可以想像10 20 30 10 20 30 ...無限的數組,在單數位置是有線的長度,雙數位置是無線的長度,實現如下:
struct StrokeStyleExample: View {
    var body: some View {
        let strokeStyle10 = StrokeStyle(lineWidth: 20, lineCap: .butt, lineJoin: .bevel, dash: [10])
        let strokeStyle20 = StrokeStyle(lineWidth: 20, lineCap: .butt, lineJoin: .bevel, dash: [20])
        let strokeStyle30 = StrokeStyle(lineWidth: 20, lineCap: .butt, lineJoin: .bevel, dash: [10, 20, 30])
        VStack {
            HorizontalLine(y: 50).stroke(.green, style: strokeStyle10)
            HorizontalLine(y: 100).stroke(.green, style: strokeStyle20)
            HorizontalLine(y: 150).stroke(.green, style: strokeStyle30)
        }
    }
}
6. 參數dashPhase就是dash虛線的開始樣式:
struct StrokeStyleExample: View {
    var body: some View {
        let strokeStyle10 = StrokeStyle(lineWidth: 20, lineCap: .butt, lineJoin: .bevel, dash: [10], dashPhase: 30)
        let strokeStyle20 = StrokeStyle(lineWidth: 20, lineCap: .butt, lineJoin: .bevel, dash: [20], dashPhase: 30)
        let strokeStyle30 = StrokeStyle(lineWidth: 20, lineCap: .butt, lineJoin: .bevel, dash: [10, 20, 30], dashPhase: 30)
        VStack {
            HorizontalLine(y: 50).stroke(.green, style: strokeStyle10)
            HorizontalLine(y: 100).stroke(.green, style: strokeStyle20)
            HorizontalLine(y: 150).stroke(.green, style: strokeStyle30)
        }
    }
}