2 Expert Tips to Matched Geometry Effect You Have To Know in SwiftUI

Introduction

Cool visual effects are always fascinating. The same is true for apps. The matched geometry effect is one of the powerful features of SwiftUI, which allows developers to create beautiful custom transitions between two different views by the matchedGeometryEffect modifier. The following tips can help you make better use of the matched geometry effect in SwiftUI.

1. Always Use a Fixed Frame for Views

SwiftUI computes the size & position difference between these two views and interpolates the transition. In other words, SwiftUI need the size and position of the final view can be expected or fixed. And the simplest way is to fix the frame of the final view by the frame modiferer. In additions, developers should call the matchedGeometryEffect modifier before the frame modifier. Otherwise, apps could crash randomly with an untraceable stack.

Circle()
    .matchedGeometryEffect(id: "circle", in: animation)
    .frame(maxHeight: 100)

Good & Safe

Circle()
    .frame(maxHeight: 100)
    .matchedGeometryEffect(id: "circle", in: animation)

Not Good & Not Safe

Using matchedGeometryEffect modifier with the frame modifier is the most circle rule when the layout is complicated because there is no way to debug the transition that is interpolated by SwiftUI by now.

2. Fix the Existing Animation ID Warning

How to deal with the start view after a transition by matchedGeometryEffect? Just remove it. For an instance, let’s make a transition between a small circle and a big one.

Good Practice. Keep only one view in the ZStack.

struct ContentView: View {
    
    @State var showBigger = false
    
    @Namespace var animation
    
    var body: some View {
        
        ZStack {
            
            if showBigger {
                
                Circle()
                    .fill(Color.green)
                    .matchedGeometryEffect(id: "ID", in: animation)
                    .frame(width: 200, height: 200)
                    .onTapGesture {
                        withAnimation {
                            showBigger.toggle()
                        }
                    }
            } else {
                
                Circle()
                    .fill(Color.green)
                    .matchedGeometryEffect(id: "ID", in: animation)
                    .frame(width: 100, height: 100)
                    .onTapGesture {
                        withAnimation {
                            showBigger.toggle()
                        }
                    }
            }
        }
    }
}

Run on a simulator, and you can found no warning outputs in console. Therefore, it is perfect.

Bad Practice. Hide the small circle by setting its opacity to zero.

struct ContentView: View {
    
    @State var showBigger = false
    
    @Namespace var animation
    
    var body: some View {
        
        ZStack {
            
            Circle()
                .fill(Color.green)
                .matchedGeometryEffect(id: "ID", in: animation)
                .frame(width: 100, height: 100)
                .opacity(showBigger ? 0 : 1)
                .onTapGesture {
                    withAnimation {
                        showBigger.toggle()
                    }
                }
            
            if showBigger {
                
                Circle()
                    .fill(Color.green)
                    .matchedGeometryEffect(id: "ID", in: animation)
                    .frame(width: 200, height: 200)
                    .onTapGesture {
                        withAnimation {
                            showBigger.toggle()
                        }
                    }
            }
        }
    }
}

In contrast to the best practice, you can found a warning output in the console, even though the app runs well as the best practice. The reason is that the current layout contains two views with the same animation ID. Why? Because the small circle is not removed from the current layouts when the showBigger is true.

Warning in Bad Practice

Why you should fix this warning? Because an unexpected transition between the start view and the final view always happens in a complicated scene, even the animation will fail.

Conclusion

In summary, matched geometry effect is powerful to build an awesome transition between two views. However, as we have talked about above, developers should keep in best practice. Otherwise, the animation may be out of control. Restate these two important tips here. One is always using a fixed frame for views, the other one is fixing the existing animation ID warning. Right now, open your Xcode and learn in practice!

Welcome to comment on this blog below and share this blog to your social media or any other place.

Hope it helps and thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *