🔹view.clipShape()

╱🚧 under construction

SwiftUIviewmodifierrendering.clipShape()

👉 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?