列表未在 DestinationView 中传播更新
List is not propagating updates in DestinationView
详细视图完全呈现后,时钟将冻结。
如果您将 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] = [=10=]
clocks[1] = [=10=]
clocks[2] = [=10=]
}
}
var formatter: DateFormatter {
let formatter = DateFormatter()
formatter.timeStyle = .medium
return formatter
}
}
您的目的地 (Text
) 只是从 clocks
捕获一个静态时刻 (Date
),并不知道它正在更新。
为什么这发生在 List
而不是 ScrollView
有点神秘,但我假设 SwiftUI
正在做一些事情来尝试确定 List
行是否相同,如果它认为不需要重新呈现它们,为了提高效率,ScrollView
和 VStack
不这样做。
这是一个可能的解决方案,它使用 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
}
}
详细视图完全呈现后,时钟将冻结。
如果您将 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] = [=10=]
clocks[1] = [=10=]
clocks[2] = [=10=]
}
}
var formatter: DateFormatter {
let formatter = DateFormatter()
formatter.timeStyle = .medium
return formatter
}
}
您的目的地 (Text
) 只是从 clocks
捕获一个静态时刻 (Date
),并不知道它正在更新。
为什么这发生在 List
而不是 ScrollView
有点神秘,但我假设 SwiftUI
正在做一些事情来尝试确定 List
行是否相同,如果它认为不需要重新呈现它们,为了提高效率,ScrollView
和 VStack
不这样做。
这是一个可能的解决方案,它使用 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
}
}