在我的项目中,我们不断更新组件。在特定的屏幕中,我们有一个带有动态项目列表的 TabView,这些项目可能会更新。问题是:如果这些项目位于具有 .tabViewStyle(.page) 的 TabView 内,则更新的项目不会更新。我制作了一个可以重现此行为的示例代码:
struct TextUIModel: Identifiable, Equatable {
let id = UUID()
let title: String
let state: String
}
public class TextUIViewModel: ObservableObject {
@Published var models: [TextUIModel] = [
.init(title: "Title", state: "1"),
.init(title: "Title", state: "2")
]
func updateModel() {
models[0] = .init(title: "Title", state: "2")
}
}
public struct TextUIModelsContentView: View {
@StateObject var viewModel: TextUIViewModel = .init()
public init() {}
public var body: some View {
if viewModel.models.isEmpty {
Text("Empty")
} else {
TabViewForTExtUIModels(models: viewModel.models)
}
Button("Update states") { viewModel.updateModel() }
}
}
struct TabViewForTExtUIModels: View {
let models: [TextUIModel]
var body: some View {
VStack {
if !models.isEmpty {
TabView {
ForEach(models) { model in
VStack {
Text(model.title)
Text(model.state)
}
}
}
.tabViewStyle(.page)
} else {
EmptyView()
}
}
}
}
按下按钮时,没有任何反应,但如果我将 TabView 更改为 ScrollView 则有效:
struct TabViewForTExtUIModels: View {
let models: [TextUIModel]
var body: some View {
VStack {
if !models.isEmpty {
ScrollView {
LazyHStack {
ForEach(models) { model in
VStack {
Text(model.title)
Text(model.state)
}
}
}
}
} else {
EmptyView()
}
}
}
}
我尝试使用状态和绑定来管理更新,但没有任何效果
具有 .tabViewStyle(.page) 的 TabView 行为是需求的一部分
我尝试了很多方法,但没有任何效果,只能去掉不是一个选项的 TabView。
有人可以帮助我吗?
此问题似乎与 SwiftUI 处理
TabView
和 .tabViewStyle(.page)
更新的方式有关。此问题的常见解决方法是向 .id
添加 TabView
修饰符。这会强制 SwiftUI 在 id 更改时重新创建 TabView
,从而导致视图更新。以下是修改您的 TabViewForTExtUIModels
:
斯威夫特
struct TabViewForTExtUIModels: View {
let models: [TextUIModel]
var body: some View {
VStack {
if !models.isEmpty {
TabView {
ForEach(models) { model in
VStack {
Text(model.title)
Text(model.state)
}
}
}
.tabViewStyle(.page)
.id(models.count) // Add this line
} else {
EmptyView()
}
}
}
}
在此代码中,
models.count
用作id。因此,每当模型数量发生变化时(即,当更新某个项目时),SwiftUI 都会重新创建 TabView
,导致其更新1。请注意,这是一种解决方法,可能并非在所有情况下都有效,或者可能会产生副作用。进行此类更改后彻底测试您的应用程序始终是个好主意。如果问题仍然存在,我建议联系 Apple 开发者论坛。