Skip to main content
Removed redundant tag info from title
Source Link
Ken White
  • 126.2k
  • 15
  • 237
  • 476

SwiftUI Hero animation not working in List when setting row's id dynamically

I tried to hardcodehard-code id for largeGreen inside .matchedGeometryEffect(id: 3, in: namespace) to check if animation would work, and it does:

Animation with hardcodedhard-coded id is the expected result, but obviously it's only working for the 3rd row. Is it even possible to achieve this effect for a green container in every row?

SwiftUI Hero animation not working in List when setting row's id dynamically

I tried to hardcode id for largeGreen inside .matchedGeometryEffect(id: 3, in: namespace) to check if animation would work and it does:

Animation with hardcoded id is the expected result, but obviously it's only working for the 3rd row. Is it even possible to achieve this effect for green container in every row?

Hero animation not working in List when setting row's id dynamically

I tried to hard-code id for largeGreen inside .matchedGeometryEffect(id: 3, in: namespace) to check if animation would work, and it does:

Animation with hard-coded id is the expected result, but obviously it's only working for the 3rd row. Is it even possible to achieve this effect for a green container in every row?

Updated title to reach more people
Link
rdev
  • 158
  • 13

How to perform SwiftUI Hero animation not working in SwiftUI's List row?when setting row's id dynamically

Source Link
rdev
  • 158
  • 13

How to perform Hero animation in SwiftUI's List row?

Recently ran into an issue trying to perform Hero animation using matchedGeometryEffect in SwiftUI. My issue is that setting id for matchedGeometryEffect effect dynamically isn't working as expected.

This is what I have so far:

import SwiftUI struct HeroAnimationTest: View { let items: [Item] = [.init(id: 1), .init(id: 2), .init(id: 3), .init(id: 4)] @State var selectedItemInRowIndex: Int? = nil @Namespace var namespace var body: some View { List { ForEach(items, id: \.id) { item in ItemListRow(namespace: namespace, item: item) { tappedItem in withAnimation { selectedItemInRowIndex = tappedItem.id } } } .listRowSeparator(.hidden) .listRowBackground(Color.clear) .listRowInsets(EdgeInsets(h: 16, v: 8)) } .animation(.spring(), value: selectedItemInRowIndex) .scrollIndicators(.never) .listStyle(.plain) .overlay { if selectedItemInRowIndex != nil { largeGreen } } } var largeGreen: some View { ZStack { Color.black .onTapGesture { withAnimation { selectedItemInRowIndex = nil } } Color.green .frame(width: 200, height: 400) .matchedGeometryEffect(id: selectedItemInRowIndex, in: namespace) Text("ID -> \(selectedItemInRowIndex ?? 0)") } } } struct HeroAnimationTest_Previews: PreviewProvider { static var previews: some View { HeroAnimationTest() } } struct Item { let id: Int } struct ItemListRow: View { @State var enlargeElement = false let namespace: Namespace.ID let item: Item let onGreenTap: (Item) -> Void var body: some View { HStack { Text("ID -> \(item.id)") VStack { Color.green } .frame(width: 100, height: 40) .matchedGeometryEffect(id: item.id, in: namespace) .onTapGesture { onGreenTap(item) } VStack { Color.yellow } .frame(width: 100, height: 40) } } } 

Current result:

enter image description here

I tried to hardcode id for largeGreen inside .matchedGeometryEffect(id: 3, in: namespace) to check if animation would work and it does:

enter image description here

Animation with hardcoded id is the expected result, but obviously it's only working for the 3rd row. Is it even possible to achieve this effect for green container in every row?

I'd really appreciate if anyone could take a look and give me some hint of what I'm missing here. I've been looking at this for a few hours now, but still can't figure out what went wrong.