╱🚧 under construction
Last updated 2 months ago
Was this helpful?
SwiftUI ⟩ view ⟩ modifier ⟩ rendering ⟩ .clipShape()
.clipShape()
裁掉 view 在指定 shape 外面的部分。
⭐️ 注意:.clipShape() 不會改變 frame
mismatching types AnyShape:裡面有 MyAnyShape (custom type erasure) 的定義 has non-Sendable type:裡面有 MyShape (custom enum) 的定義
MyAnyShape
MyShape
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 的部分裁掉
也可以考慮用view.mask() 達到類似效果。
用 enum 封裝不同型別:使用 .clipShape() 時可考慮此方法
AnyShape
type erasure
mismatching types
has non-Sendable type:裡面有 MyShape (custom enum) 的定義