This is just me wrapping my head around ViewBuilders and the new SwiftUI paradigm.
I have a "menu" at the top of my screen along with a couple of buttons.
If I do a search (tap the magnifying glass), when I return the index always returns to 0 and the first item is selected/displayed. I want to return to the same index it was at when called away. How do I remember the index and reset it?
Here's the Main Menu:
struct TopLevelMenu: View {
/// Toggle to display the Game State (Map) on button tap
@State private var shouldShowWorldMap = false
var body: some View {
NavigationView {
VStack {
if shouldShowWorldMap {
ZStack {
AnimatedSequence()
.modifier(SystemServices())
} else {
TopLevelView()
}
}
}
}
}
struct TopLevelView: View {
/// Tracks the sheet presentation and current play environment (continent)
/// mapCenter, display flags, gameOver flat, current continent
var gameState: GameState = GameState.shared
/// Handles the game logic, turns, scoring, etc.
var gameManager: GameManager = GameManager.shared
/// current game modes: continent, country, capital, grid, about
@State private var continentIndex = 0
/// If Help or the World Map is not displayed (triggered by buttons at the top), then this is the Main Display after launch
var body: some View {
VStack {
Section {
Picker(selection: $continentIndex, label: Text("N/A")) {
ForEach(0 ..< 5) {
Text(Continent.continents[$0]).tag($0)
}
}
.pickerStyle(SegmentedPickerStyle())
}
SecondLevelView(continentIndex: continentIndex)
.modifier(SystemServices())
}
}
}
Normally I would write UIKit code to save the index and restore it, but I'm unsure where such code would go since ViewBuilders aren't cooperative with inlined code. What is accepted practice?
I decided to go with the @AppStorage
property wrapper.
Since the picker options correspond to the raw values of an enum, I added a key to the enum (ContinentType):
static var key = "ContinentIndex"
Then in the View I replaced:
@State private var continentIndex = 0
with:
@AppStorage(ContinentType.key) var selectedContinentIndex = 0
This remembers the last index selected, so I can navigate away to other game modes, but when I return to this view, it remembers which continent I was working with.
Here's the update in context:
Section {
Picker(selection: $selectedContinentIndex, label: Text("Continent")) {
ForEach(0 ..< 5) {
Text(ContinentType.continents[$0]).tag($0)
}
}
.pickerStyle(SegmentedPickerStyle())
}