为什么@Published 更新Text 但不更新List?
Why @Published updates Text but doesn't update List?
我不明白为什么 Text
更新而 List
不更新。
我有一个带有 @Published
的模型,它是一个日期数组。
还有一种方法可以根据日期生成文本。
这是一个简化版本:
class DataModel: NSObject, ObservableObject {
@Published var selectedDates: [Date] = []
func summary() -> String {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "\(someOtherStuff) \(date.dateFormatted)"
lines.append(l)
}
return lines.joined(separator: "\n")
}
}
然后我在我的视图中显示了这段文字。这是一个简化版本:
struct DataView: View {
@ObservedObject var model: DataModel
var body: some View {
ScrollView {
Text(model.summary())
}
}
}
有效:当用户从视图中的 UI 添加日期到 model.selectedDates
时,摘要文本已正确更新。
现在我想用行列表替换文本。
我改方法:
func summary() -> [String] {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "\(someOtherStuff) \(date.dateFormatted)"
lines.append(l)
}
return lines
}
并更改视图:
var body: some View {
ScrollView {
List {
ForEach(model.summary(), id: \.self) { line in
Text(line)
}
}
}
}
但这不起作用:列表中根本没有文本,当用户向 model.selectedDates
添加日期时,它永远不会更新。
我做错了什么?
我能够在 SO 上找到 到之前的 post,这可能是您问题的解决方案。当您说列表中根本没有文本时,您是否进行了调试以验证这一点,或者只是屏幕上没有显示任何数据?
当我复制你的代码片段并摆弄它时,看起来列表中确实有列表试图在屏幕上显示的数据,但列表的框架被覆盖了滚动视图。将所有内容嵌套在 GeometryReader 中并为 List 提供框架大小,为程序提供了您正在寻找的功能。
为您的数据使用 ScrollView 或 List。如果一个列表有多个值,它会自动变成一个可滚动的列表。所以,我相信您可以完全删除 ScrollView。
这是一个固定的工作变体(有一些复制 - 所以您需要将其调整回您的项目)。
测试 Xcode 12.1 / iOS 14.1
class DataModel: NSObject, ObservableObject {
@Published var selectedDates: [Date] = []
func summary() -> [String] {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "someOtherStuff \(date)"
lines.append(l)
}
return lines
}
}
struct DataView: View {
@ObservedObject var model: DateDataModel = DataModel()
var body: some View {
VStack {
Button("Add") { model.selectedDates.append(Date())}
List {
ForEach(model.summary(), id: \.self) { line in
Text(line)
}
}
}
}
}
我不明白为什么 Text
更新而 List
不更新。
我有一个带有 @Published
的模型,它是一个日期数组。
还有一种方法可以根据日期生成文本。
这是一个简化版本:
class DataModel: NSObject, ObservableObject {
@Published var selectedDates: [Date] = []
func summary() -> String {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "\(someOtherStuff) \(date.dateFormatted)"
lines.append(l)
}
return lines.joined(separator: "\n")
}
}
然后我在我的视图中显示了这段文字。这是一个简化版本:
struct DataView: View {
@ObservedObject var model: DataModel
var body: some View {
ScrollView {
Text(model.summary())
}
}
}
有效:当用户从视图中的 UI 添加日期到 model.selectedDates
时,摘要文本已正确更新。
现在我想用行列表替换文本。
我改方法:
func summary() -> [String] {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "\(someOtherStuff) \(date.dateFormatted)"
lines.append(l)
}
return lines
}
并更改视图:
var body: some View {
ScrollView {
List {
ForEach(model.summary(), id: \.self) { line in
Text(line)
}
}
}
}
但这不起作用:列表中根本没有文本,当用户向 model.selectedDates
添加日期时,它永远不会更新。
我做错了什么?
我能够在 SO 上找到
当我复制你的代码片段并摆弄它时,看起来列表中确实有列表试图在屏幕上显示的数据,但列表的框架被覆盖了滚动视图。将所有内容嵌套在 GeometryReader 中并为 List 提供框架大小,为程序提供了您正在寻找的功能。
为您的数据使用 ScrollView 或 List。如果一个列表有多个值,它会自动变成一个可滚动的列表。所以,我相信您可以完全删除 ScrollView。
这是一个固定的工作变体(有一些复制 - 所以您需要将其调整回您的项目)。
测试 Xcode 12.1 / iOS 14.1
class DataModel: NSObject, ObservableObject {
@Published var selectedDates: [Date] = []
func summary() -> [String] {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "someOtherStuff \(date)"
lines.append(l)
}
return lines
}
}
struct DataView: View {
@ObservedObject var model: DateDataModel = DataModel()
var body: some View {
VStack {
Button("Add") { model.selectedDates.append(Date())}
List {
ForEach(model.summary(), id: \.self) { line in
Text(line)
}
}
}
}
}