列表未在 DestinationView 中传播更新

Posted

技术标签:

【中文标题】列表未在 DestinationView 中传播更新【英文标题】:List is not propagating updates in DestinationView 【发布时间】:2021-02-06 18:35:05 【问题描述】:

一旦详细视图完全呈现,时钟将冻结。

如果您将List 替换为ScrollView/VStack,则传播将进行。

struct ContentView: View 

    @State private var clocks = [Date(), Date(), Date()]
    
    var body: some View 
        NavigationView 
            List 
                ForEach(clocks.indices)  idx in
                    NavigationLink(destination: Text(clocks[idx], formatter: formatter)) 
                        Text("Counter \(idx)")
                    
                
            
        
        .onReceive(Timer.publish(every: 1, on: .main, in: .default).autoconnect()) 
            clocks[0] = $0
            clocks[1] = $0
            clocks[2] = $0
        
    
    
    var formatter: DateFormatter 
        let formatter = DateFormatter()
        formatter.timeStyle = .medium
        return formatter
    

【问题讨论】:

【参考方案1】:

您的目的地 (Text) 只是从 clocks 捕捉静态时刻 (Date),并没有意识到它正在更新。

为什么这发生在List 而不是ScrollView 有点神秘,但我会假设SwiftUI 正在做一些事情来尝试确定List 行是否是相同,如果它认为不需要重新渲染它们,则不会重新渲染它们,以提高效率,ScrollViewVStack 不这样做。

这是一个可能的解决方案,它使用 ObservableObject 视图模型在视图之间传递数据并通过 Published 属性保持更新。

class ViewModel : ObservableObject 
    @Published var time = Date()
    @Published var clocks = [Date(), Date(), Date()]
    
    var cancellable : AnyCancellable?
    
    init() 
        cancellable = Timer.publish(every: 1, on: .main, in: .default)
            .autoconnect()
            .sink  (date) in
                self.clocks[0] = date
                self.clocks[1] = date
                self.clocks[2] = date
                print(date)
            
    


struct ContentView: View 

    @ObservedObject var viewModel = ViewModel()
    
    var body: some View 
        NavigationView 
            List 
                ForEach(viewModel.clocks.indices)  idx in
                    NavigationLink(destination: DetailView(index: idx, viewModel: viewModel)) 
                        Text("Counter \(idx)")
                    
                
            
        .navigationViewStyle(StackNavigationViewStyle())
    



struct DetailView : View 
    var index : Int
    @ObservedObject var viewModel : ViewModel
    
    var body: some View 
        Text(viewModel.clocks[index], formatter: formatter)
    
    
    var formatter: DateFormatter 
            let formatter = DateFormatter()
            formatter.timeStyle = .medium
            return formatter
        

【讨论】:

恕我直言,将格式化程序设为 static 是一个好习惯 - 每次计算正文时都会重新创建计算属性。可以在此处找到示例:How to format text inside text views. 绝对正确——没有从 OP 的代码中解决这个问题

以上是关于列表未在 DestinationView 中传播更新的主要内容,如果未能解决你的问题,请参考以下文章

嵌套 ControlValueAccessor 的角度验证状态未在父级中正确传播,如何实现此验证?

didSelectRowAtIndexPath 不以编程方式导航到destinationView

Spring Boot 2 OIDC(OAuth2)客户端/资源服务器未在 WebClient 中传播访问令牌

jQuery mobile 未在列表中显示正确的选定项目

python中有没有办法解压缩类似于javascript中的传播运算符的列表? [复制]

图像未在列表中显示,反应