最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - SwiftUI: matchedGeometryEffect and clipShape Animation Bug - Stack Overflow

programmeradmin3浏览0评论

Say I have a container view that I use to apply consistent styling to various contained views.

struct FormattedContainer<Content: View>: View {
    let content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
            content
                .padding()
                .background(Color.gray.opacity(0.2))
    }
}

I use it to enclose a couple of views that use matchedGeometryEffect to animate from one container to another.

struct ContentView: View {
    @Namespace var animation
    @State var isFlipped: Bool = false

    var body: some View {
        VStack {
            FormattedContainer {
                HStack {
                    Rectangle()
                    if isFlipped {
                        Text("This is the active container")
                            .layoutPriority(1)
                            .matchedGeometryEffect(id: "id", in: animation)
                    }
                }
            }
            Spacer(minLength: 40)
            FormattedContainer {
                HStack{
                    if !isFlipped {
                        Text("This is the active container")
                            .layoutPriority(1)
                            .matchedGeometryEffect(id: "id", in: animation)
                    }
                    Rectangle()
                }
            }
        }
        .contentShape(Rectangle())
        .padding()
        .onTapGesture {
            withAnimation {
                isFlipped.toggle()
            }
        }
    }
}

This works well and look like this:

If I add a clip shape to my container to give it rounded corners:

struct FormattedContainer<Content: View>: View {
    let content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
            content
                .padding()
                .background(Color.gray.opacity(0.2))
                .clipShape(RoundedRectangle(cornerRadius: 20)) <----- added line
    }
}

The animation disappears when moving from container to container:

Any ideas how to fix the formatted container so it has rounded corners and the animation doesn't disappear?

Say I have a container view that I use to apply consistent styling to various contained views.

struct FormattedContainer<Content: View>: View {
    let content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
            content
                .padding()
                .background(Color.gray.opacity(0.2))
    }
}

I use it to enclose a couple of views that use matchedGeometryEffect to animate from one container to another.

struct ContentView: View {
    @Namespace var animation
    @State var isFlipped: Bool = false

    var body: some View {
        VStack {
            FormattedContainer {
                HStack {
                    Rectangle()
                    if isFlipped {
                        Text("This is the active container")
                            .layoutPriority(1)
                            .matchedGeometryEffect(id: "id", in: animation)
                    }
                }
            }
            Spacer(minLength: 40)
            FormattedContainer {
                HStack{
                    if !isFlipped {
                        Text("This is the active container")
                            .layoutPriority(1)
                            .matchedGeometryEffect(id: "id", in: animation)
                    }
                    Rectangle()
                }
            }
        }
        .contentShape(Rectangle())
        .padding()
        .onTapGesture {
            withAnimation {
                isFlipped.toggle()
            }
        }
    }
}

This works well and look like this:

If I add a clip shape to my container to give it rounded corners:

struct FormattedContainer<Content: View>: View {
    let content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
            content
                .padding()
                .background(Color.gray.opacity(0.2))
                .clipShape(RoundedRectangle(cornerRadius: 20)) <----- added line
    }
}

The animation disappears when moving from container to container:

Any ideas how to fix the formatted container so it has rounded corners and the animation doesn't disappear?

Share Improve this question asked Mar 27 at 2:50 colbrewcolbrew 1011 silver badge9 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

You should not clip content. You can add an in: parameter to specify what shape the background should be in:

.background(Color.gray.opacity(0.2), in: .rect(cornerRadius: 20))
// remove clipShape!

If you do need clipShape to clip other content, you need to use a third Text on top of everything to match the geometry of one of the other Texts.

VStack {
    FormattedContainer {
        HStack {
            Rectangle()
            if isFlipped {
                Text("This is the active container")
                    .hidden()
                    .layoutPriority(1)
                    .matchedGeometryEffect(id: true, in: animation)
            }
        }
    }
    Spacer(minLength: 40)
    FormattedContainer {
        HStack{
            if !isFlipped {
                Text("This is the active container")
                    .hidden()
                    .layoutPriority(1)
                    .matchedGeometryEffect(id: false, in: animation)
            }
            Rectangle()
        }
    }
}
.contentShape(Rectangle())
.padding()
.onTapGesture {
    withAnimation {
        isFlipped.toggle()
    }
}
.overlay {
    // this is the only Text you see!
    // it matches the geometry of either the top container's or bottom container's text depending on isFlipped
    Text("This is the active container")
        .matchedGeometryEffect(id: isFlipped, in: animation, isSource: false)
}
发布评论

评论列表(0)

  1. 暂无评论