0

我有一个基于一些状态变量的观点。这些状态由 API 调用的完成块设置。它们显示bookings 为ForEach列表,我希望它们与slide过渡一起出现。

slide过渡效果很好。由于我添加了!isLoading检查,这些动画不再显示。现在出现的所有动画都是淡入淡出的ProgressView。删除!isLoading检查时,交错的幻灯片动画又回来了,但我想保留此检查,以便我可以正确处理加载状态。

这是重现该问题的独立代码:

import SwiftUI

struct RoomView: View {
    
    @State private var room: String?
    @State private var bookings: [String]?
    @State private var isLoading: Bool = false
    
    var body: some View {
        VStack(spacing: 0) {
            if /* This is the problematic condition !isLoading, */ let room = self.room {
                ScrollView {
                    LazyVStack(alignment: .leading) {
                        Text(room)
                        
                        if let bookings = bookings {
                            ForEach(bookings.indices) { (index) in
                                let booking = bookings[index]
                                VStack(alignment: .leading) {
                                    Text(booking)
                                    Divider()
                                }
                                .transition(.slide)
                                // Stagger the animations when displaying the list
                                .animation(Animation.spring().delay(0.04 * Double(index)))
                            }
                        }
                    }
                    .padding()
                }
            } else {
                // If we're loading
                ProgressView("Loading Room")
            }
        }
        .transition(.opacity)
        .animation(.easeInOut)
        .onAppear {
            self.isLoading = true
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                self.room = "Demo room"
                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                    withAnimation {
                        self.bookings = ["Booking 1", "Booking 2", "Booking 3", "Booking 4", "Booking 5"]
                        self.isLoading = false
                    }
                }
            }
        }
    }
}

struct RoomView_Previews: PreviewProvider {
    static var previews: some View {
        RoomView()
    }
}

SwiftUI 动画是否存在一个已知问题,即具有多个条件可能会导致过渡不出现?我该如何解决这个问题,以便在ProgressView不删除!isLoading检查的情况下保持交错动画和淡入淡出?

4

1 回答 1

0

这是可能的解决方案 - 使视图独立。使用 Xcode 12 / iOS 14 测试。

演示

struct RoomView: View {
    
    @State private var room: String?
    @State private var bookings: [String]?
    @State private var isLoading: Bool = false
    
    var body: some View {
        ZStack {
            if isLoading {
                // If we're loading
                ProgressView("Loading Room")
            }
            if let room = self.room {
                ScrollView {
                    LazyVStack(alignment: .leading) {
                        Text(room)
                        
                        if let bookings = bookings {
                            ForEach(bookings.indices) { (index) in
                                let booking = bookings[index]
                                VStack(alignment: .leading) {
                                    Text(booking)
                                    Divider()
                                }
                                .transition(.slide)
                                // Stagger the animations when displaying the list
                                .animation(Animation.spring().delay(0.04 * Double(index)))
                            }
                        }
                    }
                    .padding()
                }
            }
        }
        .transition(.opacity)
        .animation(.easeInOut)
        .onAppear {
            self.isLoading = true
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                self.room = "Demo room"
                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                    withAnimation {
                        self.bookings = ["Booking 1", "Booking 2", "Booking 3", "Booking 4", "Booking 5"]
                        self.isLoading = false
                    }
                }
            }
        }
    }
}
于 2020-10-08T19:10:45.117 回答