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的代码中解决这个问题