🔹view.clipShape()
╱🚧 under construction
SwiftUI ⟩ view ⟩ modifier ⟩ rendering ⟩ .clipShape()
⭐️ 注意:.clipShape()
不會改變 frame❗
👉 mismatching types
👉 AnyShape:裡面有 MyAnyShape
(custom type erasure) 的定義
👉 has non-Sendable type:裡面有 MyShape
(custom enum) 的定義
import SwiftUI
struct TempView: View {
@State var isOn = false
private let size: CGFloat = 20
var body: some View {
VStack {
text
Toggle("切換", isOn: $isOn)
.padding()
}
}
// ⭐️ 注意:
// 這裏用了三個方案,三個的回傳型別都不同(AnyShape, MyShape, MyAnyShape),
// 所以 return type 必須用 `some Shape`,讓 compiler 自行判斷。
private var dynamicShape: some Shape {
// ⭐️ 方案一:使用 AnyShape (official type erasure)
// isOn ? AnyShape(circle) : AnyShape(roundedRect)
// ⭐️ 方案二:使用 MyShape (custom enum)
// isOn ? MyShape.circle : MyShape.roundedRect(
// cornerSize: CGSize(width: size, height: size)
// )
// ⭐️ 方案三:使用 MyAnyShape (custom type erasure)
isOn ? MyAnyShape(circle) : MyAnyShape(roundedRect)
}
private var text: some View {
Text("Clipped text in a circle")
.frame(width: 175, height: 100)
.foregroundColor(Color.white)
.background(Color.blue)
// ------------------------------------------------
// ⭐️ 若使用動態形狀時,必須想辦法消除不同形狀的型別問題
.clipShape(dynamicShape)
// 🐞 下面的寫法會產生 "mismatching types" 的錯誤
.clipShape(isOn ? Circle() : Capsule())
// ------------------------------------------------
.animation(.default, value: isOn)
}
private var roundedRect: some Shape {
RoundedRectangle(cornerSize:
CGSize(width: size, height: size)
)
}
private var circle: some Shape {
Circle()
}
}
Last updated
Was this helpful?