在下面的示例代码中,希望它不要太长,我很难正确地完成它。起初,我确实想使用具有关联值和操作的枚举,但选择了一种我确实更好理解的方式。
在我当前的代码中,.tag 让我有点头疼,我确实尝试了几种方法来使其正确,但没有任何效果。它显示的错误是“.tag(item.tag)”行和“.tabItem”行上的“引用静态方法“buildExpression”时没有完全匹配”。
import SwiftUI
class SettingsTabItemManager: ObservableObject {
@Published var tabItems: [SettingsTabItem] = []
init() {
createTabItems()
}
func createTabItems() {
self.tabItems = [
SettingsTabItem(
label: "General",
labelImage: "gear",
tag: "general",
action: {},
view: GeneralSettingsView(),
description: "The general settings tabItem"),
SettingsTabItem(
label: "Network",
labelImage: "network",
tag: "network",
action: {},
view: NetworkSettingsView(),
description: "The network settings tabItem"),
SettingsTabItem(
label: "Advanced",
labelImage: "star",
tag: "advanced",
action: {},
view: AdvancedSettingsView(),
description: "The advanced settings tabItem")
]
}
}
struct SettingsTabItem {
var id : UUID = UUID()
var label: String
var labelImage: String
var tag: String // or enum Tabs
var action: () -> Void
var view: any View
var description: String
}
struct SettingsView: View {
@StateObject private var tabItemManager = SettingsTabItemManager()
@State private var selectedTab: String?
init() {
_selectedTab = State(initialValue: tabItemManager.tabItems.first?.tag)
}
@State var tapped = false
var body: some View {
TabView {
Group {
ForEach(tabItemManager.tabItems, id: \.id) { item in
item.view
.tabItem {
Label(item.label, systemImage: item.labelImage)
}
.tag(item.tag) // I did try also ( .tag(item.tag.hashValue) )
}
.onTapGesture {
tapped.toggle()
// more is comming
}
}
.padding(20)
.frame(width: 375, height: 150)
}
}
}
struct GeneralSettingsView: View {
var body: some View {
Text("GeneralSettingsView")
}
}
struct NetworkSettingsView: View {
var body: some View {
Text("NetworkSettingsView")
}
}
struct AdvancedSettingsView: View {
var body: some View {
Text("AdvancedSettingsView")
}
}
我在这里忽略了什么?也许我应该采取不同的做法,但这就是我想到的。也许我应该使用某种视图生成器,但不知道该怎么做。 预先感谢。
您的
View
中不应有 SettingsTabItem
。
var view: any View // remove this!
我假设您希望能够动态更改选项卡视图中的选项卡,这就是您创建
SettingsTabItem
结构的原因。因此 SettingsTabItem
数组代表 state,SwiftUI 中的视图是状态的函数。
您应该编写一个函数,给定
SettingsTabItem
,返回一些 View
。例如,在您在这里展示的简单案例中:
@ViewBuilder
func tabView(forTabItem tabItem: SettingsTabItem) -> some View {
switch tabItem.tag { // also consider using an enum for the tag
case "general":
GeneralSettingsView()
case "network":
NetworkSettingsView()
case "advanced":
AdvancedSettingsView()
default:
EmptyView()
}
}
您可以扩展此函数来执行您需要执行的任何操作,以找出与给定
View
对应的 SettingsTabItem
应该是什么。在实际场景中,您可能需要向 SettingsTabItem
添加更多属性。
请注意,我通过使用
@ViewBuilder
避免了视图都具有不同类型的问题,并且只有在将视图编写为状态函数时才能做到这一点。您尝试使用 any View
来解决此问题,但这导致了错误。
然后你就可以在
ForEach
中调用这个函数了:
tabView(forTabItem: item)
.tabItem {
Label(item.label, systemImage: item.labelImage)
}
.tag(item.tag)