繁体   English   中英

SwiftUI 自定义列表与 ForEach 删除 animation 不起作用

[英]SwiftUI custom list with ForEach delete animation not working

我正在创建一个显示时间信息的自定义列表(分钟和秒,在下面的代码段中未使用以简化代码)。 当用户向列表中添加一个条目时,我设法实现了一个不错的 animation,但删除一个条目没有 animation(第一个 GIF)。

使用 iOS 14,animation 可以正常工作,但是,animation 仅从列表中删除最后一个矩形,然后更新每行中的文本(第二个 GIF)。 这不是我想要的——我的目标是如果一行被删除,其他行应该填满那个空间并相应地移动——使用 animation。

行的 ID 可能有问题,但我无法解决这个问题。 感谢您的帮助!

在此处输入图像描述

在此处输入图像描述

struct ContentView: View {
    @State var minutes = [0]
    @State var seconds = [0]
    @State var selectedElement = 0
    
    var body: some View {
        ScrollView(){
            VStack{
                ForEach(minutes.indices, id: \.self){ elem in
                    
                    ZStack{
                        
                        EntryBackground()
                        
                        
                        Text("\(self.minutes[elem])")
                            .transition(AnyTransition.scale)
                        
                        HStack{
                            Button(action: {
                                withAnimation(.spring()){
                                    self.seconds.remove(at: elem)
                                    self.minutes.remove(at: elem)
                                }
                                
                            })
                            {
                                Image(systemName: "minus.circle.fill")
                                    .foregroundColor(Color.red)
                                    .font(.system(size: 22))
                                    .padding(.leading, 10)
                            }
                            Spacer()
                        }
                        
                    }
                    .padding(.horizontal)
                    .padding(.top)
                    .contentShape(Rectangle())
                    .onTapGesture {
                        withAnimation(.spring()){
                            self.selectedElement = elem
                        }
                    }
                }
            }
            Spacer()
            
            Button(action: {
                withAnimation{
                    self.minutes.append(self.minutes.count)
                    self.seconds.append(0)
                }
                
            })
            {
                ZStack{
                    EntryBackground()
                    
                    Text("Add")
                    
                    HStack{
                        Image(systemName: "plus.circle.fill")
                            .foregroundColor(Color.green)
                            .font(.system(size: 22))
                            .padding(.leading, 10)
                        
                        Spacer()
                    }
                }.padding()
            }
        }
    }
}

struct EntryBackground: View {
    var body: some View {
        Rectangle()
            .cornerRadius(12)
            .frame(height: 40)
            .foregroundColor(Color.gray.opacity(0.15))
    }
}

您需要使每一行唯一标识,以便动画师知道添加了什么和删除了什么,因此正确地为每个更改设置动画。

这是可能的方法。 用 Xcode 12 / iOS 14 测试

在此处输入图像描述

struct TimeItem: Identifiable, Equatable {
    static func == (lhs: Self, rhs: Self) -> Bool {
        lhs.id == rhs.id
    }

    let id = UUID()       // << identify item
    let minutes: Int
    let seconds: Int = 0
}

struct ContentView: View {
    @State var items = [TimeItem]()
    @State var selectedElement: TimeItem?

    var body: some View {
        ScrollView(){
            VStack{
                ForEach(items){ elem in   // << work by item

                    ZStack{

                        EntryBackground()


                        Text("\(elem.minutes)")
                            .transition(AnyTransition.scale)

                        HStack{
                            Button(action: {
                                self.items.removeAll { $0.id == elem.id }
                            })
                            {
                                Image(systemName: "minus.circle.fill")
                                    .foregroundColor(Color.red)
                                    .font(.system(size: 22))
                                    .padding(.leading, 10)
                            }
                            Spacer()
                        }

                    }
                    .padding(.horizontal)
                    .padding(.top)
                    .contentShape(Rectangle())
                    .onTapGesture {
                        withAnimation(.spring()){
                            self.selectedElement = elem
                        }
                    }
                }
            }
            Spacer()

            Button(action: {
                self.items.append(TimeItem(minutes: self.items.count))
            })
            {
                ZStack{
                    EntryBackground()

                    Text("Add")

                    HStack{
                        Image(systemName: "plus.circle.fill")
                            .foregroundColor(Color.green)
                            .font(.system(size: 22))
                            .padding(.leading, 10)

                        Spacer()
                    }
                }.padding()
            }
        }.animation(.spring(), value: items)   // << animate changes
    }
}

struct EntryBackground: View {
    var body: some View {
        Rectangle()
            .cornerRadius(12)
            .frame(height: 40)
            .foregroundColor(Color.gray.opacity(0.15))
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM