0

次のアプローチを使用して、角の数 x のビューに丸みを帯びた角を追加しています。

特定の角を丸くするSwiftUI

extension View {
    func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
        clipShape( RoundedCorner(radius: radius, corners: corners) )
    }
}

struct RoundedCorner: Shape {

    var radius: CGFloat = .infinity
    var corners: UIRectCorner = .allCorners

    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        return Path(path.cgPath)
    }
}

これは非常にうまく機能します。残念ながら、角を丸くしないでこのビューを別のフレームにアニメーション化すると、cornerRadius のアニメーションはありません。他のすべてのアニメーションは問題なく動作します。

これを説明するために、標準の .cornerRadius 修飾子と、上記の拡張機能を使用したカスタム .cornerRadius 修飾子を使用した角の半径のアニメーションを以下に示します。

struct ContentView: View {
    
    @State var radius: CGFloat = 50

    var body: some View {
        VStack {
            Button {
                withAnimation(.easeInOut(duration: 2)) {
                    if radius == 50 {
                        radius = 0
                    } else {
                        radius = 50
                    }
                }
                
            } label: {
                Text("Change Corner Radius")
            }

            Color.red
                .frame(width: 100, height: 100)
                .cornerRadius(radius, corners: [.topLeft, .bottomRight])
            
            Color.blue
                .frame(width: 100, height: 100)
                .cornerRadius(radius)
        }
    }
}

ここに画像の説明を入力

4

1 に答える 1

1

問題はRoundedCorner構造体にあります。アニメーションを念頭に置いて書かれたものではありません。プロトコルに準拠する構造体Shapeはアニメーション化できvar animatableDataますが、システムがShape. この場合のように、通常はかなり簡単なので、実装する必要がない理由はわかりません。

構造体を次のように変更すると、希望RoundedCornerどおりにアニメーション化されます。

struct RoundedCorner: Shape {

    var radius: CGFloat
    var corners: UIRectCorner
    var animatableData: CGFloat {
        get { return radius }
        set { radius = newValue }
    }

    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        return Path(path.cgPath)
    }
}

ここに画像の説明を入力

于 2021-11-13T19:17:34.003 に答える