Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 列表未在DestinationView中传播更新_Swift_Swiftui_Swiftui List_Swiftui Navigationview - Fatal编程技术网

Swift 列表未在DestinationView中传播更新

Swift 列表未在DestinationView中传播更新,swift,swiftui,swiftui-list,swiftui-navigationview,Swift,Swiftui,Swiftui List,Swiftui Navigationview,详细视图完全显示后,时钟将冻结 如果将列表替换为滚动视图/VStack,传播将流动 struct ContentView:View{ @国家私有变量时钟=[Date(),Date(),Date()] var body:一些观点{ 导航视图{ 名单{ ForEach(clocks.index){idx-in 导航链接(目标:文本(时钟[idx],格式化程序:格式化程序)){ 文本(“计数器\(idx)”) } } } } .onReceive(Timer.publish(每:1,on:.main,

详细视图完全显示后,时钟将冻结

如果将
列表
替换为
滚动视图
/
VStack
,传播将流动

struct ContentView:View{
@国家私有变量时钟=[Date(),Date(),Date()]
var body:一些观点{
导航视图{
名单{
ForEach(clocks.index){idx-in
导航链接(目标:文本(时钟[idx],格式化程序:格式化程序)){
文本(“计数器\(idx)”)
}
}
}
}
.onReceive(Timer.publish(每:1,on:.main,in:.default).autoconnect()){
时钟[0]=$0
时钟[1]=0美元
时钟[2]=0美元
}
}
变量格式化程序:日期格式化程序{
let formatter=DateFormatter()
formatter.timeStyle=.medium
返回格式化程序
}
}
您的目的地(
文本
)只是从
时钟
捕获一个静态时刻(日期),并不知道它正在更新

为什么会在
列表中出现这种情况,而不是在
滚动视图中出现这种情况,这有点神秘,但我假设
SwiftUI
正在幕后进行一些工作,试图确定
列表中的行是否相同,如果它认为不需要的话,为了提高效率,不会重新呈现它们,其中
ScrollView
VStack
不起作用

下面是一个可能的解决方案,它使用
observateObject
视图模型在视图之间传递数据,并通过
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
        }
}

IMHO将格式化程序设置为静态是一种很好的做法——每次计算主体时,都会重新创建计算属性。这里可以找到一个例子:。绝对正确——没有从OP的代码中解决这个问题