I seem to struggle with Picker
. Having read the documentation, I still feel that I'm missing something.
In my project, I want to be able to switch between tabs of content. As the tabs are mutually exclusive, the Picker
seems as the best choice.
Say, my Tab
Is declared as such:
struct Tab: Identifiable, Hashable {
var id: UUID
var name: String
}
Then, as reprex, let's say I want to display the name of the tab I've chosen. After trying to get the binding on the Tab
element itself, I've found this answer on SO and tried to achieve it like this:
struct Test: View {
@State private var selectedTabIndex: Int = 0
var tabs: [Tab] = ["Work", "Hobby", "Random"].map {Tab(id: UUID(), name: $0)}
var body: some View {
VStack {
Picker("Tab", selection: $selectedTabIndex) {
ForEach(tabs) {tab in
Text(tab.name)
}
}
Text(tabs[selectedTabIndex].name)
}
}
}
This example results in the displayed name not updating. If I try to select the tab using the bounded syntax, i.e. tabs[$selectedTabIndex].name
, I get type mismatch between types - Cannot convert value of type 'Binding<Int>' to expected argument type 'Int'
. Which is understandable, but does not get me any closer.
What should I do to get this to work?
Is the index approach feasible? If so, why does the view not update? What should I read about?
Although @Claude31 example works, I realized that there is a better way to tackle the problem.
As the tag only provides conformance to the bound var type, switching type of id
from UUID
to Self
results in ForEach
tagging the entries of Picker
automatically. I don't need the redundant property, everyone is happy.
So, my solution is (cumbersomely written)
struct Tab: Identifiable, Hashable {
var id: Self { self }
var name: String
}
extension Tab {
var sampleData: [Tab] = ["Work", "Hobby", "Random"].map {Tab(name: $0)}
}
struct Test: View {
@State private var selectedTab: Tab = Tab.sampleData[0]
var body: some View {
VStack {
Picker("Tab", selection: $selectedTab) {
ForEach(Tab.sampleData) {tab in
Text(tab.name)
}
}
Text(selectedTab.name)
}
}
}
Unless there is some UUID
superiority over Self
as an identifier...