簡體   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