The Util Designer
SwiftUI 創建一個Diamond Shape
xcode 13.3.1, swift 5.5, iOS 15.4
2022-08-10
SwiftUI 內已提供了幾個常用的Shape,像Circle,Rectangle和Capsule等等。這次我們來看看如何建立自己的Shape。
1. 首先我們創建一個Diamond並繼承於Shape,實作如下:
struct Diamond : Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            
        }
    }
}
struct DiamondExample: View {
    var body: some View {
        Diamond()
    }
}
2. 然後向Diamond的path方法中添加畫diamond的代碼。
struct Diamond : Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            let width = 100
            let height = 100
            path.addLines([
                CGPoint(x: width/2, y: 0),
                CGPoint(x:width, y:height/2),
                CGPoint(x: width/2, y:height),
                CGPoint(x:0,y:height/2)
            ])
            path.closeSubpath()
        }
    }
}
struct DiamondExample: View {
    var body: some View {
        Diamond()
    }
}

3. 然後我們就可以使用像其他內建的Shape一樣去做一些控制,像外框的大小和顏色等等,以下代碼把Diamond的外框寬度設為10,顏色設為藍色。
struct DiamondExample: View {
    var body: some View {
        Diamond()
            .stroke(.blue, lineWidth: 10)
    }
}
4. 現在的Diamond所佔長寬都是100,但實際使用上應根據其元件所佔空間大小動態的去畫,func path(in rect: CGRect) -> Path中的rect就提供了其元作所佔空間,修改代碼如下:
struct Diamond : Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            let width = rect.width
            let height = rect.height
            path.addLines([
                CGPoint(x: width/2, y: 0),
                CGPoint(x:width, y:height/2),
                CGPoint(x: width/2, y:height),
                CGPoint(x:0,y:height/2)
            ])
            path.closeSubpath()
        }
    }
}
struct DiamondExample: View {
    var body: some View {
        Diamond()
            .stroke(.blue, lineWidth: 10)
    }
}
5. 現在就可以像其他內建Shape一樣設置長寛了。

struct Diamond : Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            let width = rect.width
            let height = rect.height
            path.addLines([
                CGPoint(x: width/2, y: 0),
                CGPoint(x:width, y:height/2),
                CGPoint(x: width/2, y:height),
                CGPoint(x:0,y:height/2)
            ])
            path.closeSubpath()
        }
    }
}
struct DiamondExample: View {
    var body: some View {
        
        Diamond()
            .stroke(.blue, lineWidth: 10)
            .frame(width: 200, height: 100)
    }
}
6. 也可以配搭SwiftUI的佈局元件一起使用。
struct DiamondExample: View {
    var body: some View {
        VStack {
            Diamond()
                .stroke(.blue, lineWidth: 10)
                .frame(width: 200, height: 100)
            
            Diamond()
                .stroke(.red, lineWidth: 5)
                .frame(width: 100, height: 50)
        }
    }
}
7. 還可以直接用來做圖片的切割。
struct DiamondExample: View {
    var body: some View {
        Image("cat")
            .resizable()
            .scaledToFit()
            .clipShape(
                Diamond()
            )
    }
}