MatchedGeometryEffect + Image Url

81 views Asked by At

Can someone please explain why MatchedGeometryEffect works with images from the assets folder but not from URLs? And how do we get around this so we can use MatchedGeometryEffect with actual images?

Video with Image Asset (works): https://imgur.com/rI4VcsP

Video with Image from URL (doesn't work): https://imgur.com/0KfGHRj

Code:

import SwiftUI
import Kingfisher

struct ZStackView: View {
    
    @StateObject private var VM = ViewModel()
    @Namespace private var nsspace
    @State private var selectedProfile: Profile?
    
    var body: some View {
        ZStack {
            ForEach(Array(zip(VM.profiles.indices, VM.profiles)), id: \.1) { index, profile in
                if Int(index) == 0 {
                    VStack {
                        ScrollView {
                            Text(profile.name)
                                .font(.largeTitle)
                            if selectedProfile == nil {
                                //Image("tower") // works
                                KFImage(profile.urls.first) // doesnt work
                                    .resizable()
                                    .scaledToFill()
                                    .matchedGeometryEffect(id: profile.id, in: nsspace)
                                    .frame(width: 300, height: 400)
                                    .clipped()
                                    .onTapGesture {withAnimation(.easeInOut) {
                                        VM.profiles.removeAll(where: { $0.id == profile.id})
                                    }}
                            }
                            
                            Text(profile.prompt)
                                .font(.largeTitle)
                                .onTapGesture {
                                    withAnimation {
                                        selectedProfile = profile
                                    }
                                }
                        }
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .zIndex(1)
                    .transition(AnyTransition.asymmetric(insertion: .scale, removal: .move(edge: .leading)))
                }
            }
            
            if let profile = selectedProfile {
                VStack {
                    //Image("tower") // works
                    KFImage(profile.urls.first) // doesnt work
                        .resizable()
                        .scaledToFill()
                        .matchedGeometryEffect(id: profile.id, in: nsspace)
                        .frame(width: 300, height: 400)
                        .clipped()
                }
                .frame(maxWidth: .infinity,  maxHeight: .infinity)
                .background(content: {
                    Color.blue
                })
                .onTapGesture {
                    withAnimation {
                        selectedProfile = nil
                    }
                }
                .zIndex(2)
            }
        }
    }
}
1

There are 1 answers

0
Lukas On

The order in which you apply the modifier matters. Also, from my experience, clipped() does not work well with the effect.