【问题标题】:ForEach in List stops update propagation in DestinationViewList 中的 ForEach 停止 DestinationView 中的更新传播
【发布时间】:2021-02-03 23:56:11
【问题描述】:

我认为从这个虚拟示例中非常清楚:如果您删除 ForEach 代码行,神奇地,传播将流动并且时钟将滴答作响,否则一旦出现详细视图,它将冻结。

class ModelView: ObservableObject {
    @Published var clock = Date()
    init() {
        Timer.publish(every: 1, on: .main, in: .default)
            .autoconnect()
            .print()
            .assign(to: &$clock)
    }
}

struct ContentView: View {

    @StateObject var viewModel = ModelView()
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink("Clock", destination: Text(viewModel.clock, formatter: formatter))
                ForEach(0..<1) { _ in } // <- Remove this row and the clock will work
            }
        }
    }
    
    var formatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.timeStyle = .medium
        return formatter
    }
}

【问题讨论】:

    标签: swift swiftui swiftui-list swiftui-navigationlink swiftui-navigationview


    【解决方案1】:

    我会说它在第一种情况下起作用是某种巧合,因为目的地是(或可以)在导航上复制的(这可能发生在第二种情况下)。

    正确的方法是将独立视图与自己的观察者分开以获取详细信息。如果没有绑定,父视图不应更新子视图属性。

    测试并使用 Xcode 12.4 / iOS 14.4

    struct ContentView: View {
    
        @StateObject var viewModel = ModelView()
        
        var body: some View {
            NavigationView {
                List {
                    NavigationLink("Clock", destination: DetailsView(viewModel: viewModel))
                    ForEach(0..<1) { _ in } // <- Remove this row and the clock will work
                }
            }
        }
        
    }
    
    struct DetailsView: View {
        @ObservedObject var viewModel: ModelView
        
        var body: some View {
            Text(viewModel.clock, formatter: formatter)
        }
    
        var formatter: DateFormatter {
            let formatter = DateFormatter()
            formatter.timeStyle = .medium
            return formatter
        }
    }
    

    【讨论】:

    • 我认为理想情况下,DetailsView 应该在触发更新时重绘,因为它位于状态函数的主体内。很奇怪,因为这只发生在 List(或 Form)/ForEach 组合中。任何其他纯 SwiftUI 组合都可以使用。我认为更新在某处被内部 UITableView 实现阻止。
    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 2022-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    相关资源
    最近更新 更多