🔹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()
}
}SwiftUI ⟩ View fundamentals ⟩ View ⟩ rendering modifiers
.clipShape(_:style:) : .cornerRadius() 已經廢止 (deprecated),用此 clipShape 代替
.clipped(antialiased:):將 view 突出 frame 的部分裁掉
💡 用 enum 封裝不同型別:使用
.clipShape()時可考慮此方法📦 AnyShape
也可以考慮用view.mask() 達到類似效果。
🐞 has non-Sendable type:裡面有 MyShape (custom enum) 的定義
Last updated
Was this helpful?