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)
}
}
}
}
The order in which you apply the modifier matters. Also, from my experience,
clipped()
does not work well with the effect.