Raul
Raul

Reputation: 21

swift skips first variable update

I've been doing the Standford CS193p free course online and I have a strange situation with assignment 6. I'm supposed to create a theme list from which the user can directly start a game with the chosen theme. This list can be edited and when in editMode a tap gesture is used to open a sheet from which the tapped theme is edited. For this the tap gesture takes the index of the tapped theme and stores it as chosenThemeIndex.

I don't understand why this doesn't work the first time after running the code, meaning tapping on any list item opens always index 0 the first time, regardless of tapping on an item with another index. Then when closing the editing sheet and tapping on any other list item the correct theme is opened for editing. This means for me that Swift is skipping the first update from 0 to another index on chosenThemeIndex. Why is this happening and how can I correct this?

The complete app code can be pulled from branch Assignment6 on: https://github.com/kranca/Memorize.git

import SwiftUI

struct ThemeChooser: View {
    @EnvironmentObject var store: ThemeStore

    @State private var editMode: EditMode = .inactive
    @State private var editing = false

    var body: some View {
        NavigationView {
            List {
                ForEach(store.themes) { theme in
                    let game = store.themes[theme].emojis.count > 1 ? EmojiMemoryGame(theme: theme) : nil
                    NavigationLink(destination: store.themes[theme].emojis.count > 1 ? EmojiMemoryGameView(game: game!) : nil, label: {
                        VStack(alignment: .leading) {
                            HStack {
                                VStack(alignment: .leading) {
                                    Text(theme.name)
                                    Text("Pairs: \(theme.cardPairs)")
                                }
                                RoundedRectangle(cornerRadius: 5)
                                    .size(width: 30, height: 45)
                                    .fill()
                                    .foregroundColor(Color(rgbaColor: theme.rgbaColor))
                            }
                            Text(theme.emojis)
                        }
                        // call on gesture active only when in editMode
                        .gesture(editMode == .active ? tap(on: store.themes.firstIndex(of: theme) ?? 0) : nil)
                    })
                }
                .onDelete(perform: { indexSet in
                    store.themes.remove(atOffsets: indexSet)
                })
                .onMove(perform: { indexSet, newOffset in
                    store.themes.move(fromOffsets: indexSet, toOffset: newOffset)
                })
            }
            .navigationTitle("Choose a theme!")
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) { editMode == .active ? newThemeButton : nil }
                ToolbarItem { EditButton() }
            }
            .sheet(isPresented: $editing) {
                ThemeEditor(theme: $store.themes[chosenThemeIndex])
            }
            .environment(\.editMode, $editMode)
        }
    }

    // variable I want to update
    @State private var chosenThemeIndex: Int = 0

    // gesture which takes tapped index and updates chosenThemeIndex
    func tap(on tapedThemeIndex: Int) -> some Gesture {
        TapGesture().onEnded {
            chosenThemeIndex = tapedThemeIndex
            editing = true
        }
    }

    private var newThemeButton: some View {
        Button("Add New Theme") {
            chosenThemeIndex = 0
            store.insertTheme(named: "", cardPairs: 2)
            editing = true
        }
    }
}

Upvotes: 0

Views: 68

Answers (0)

Related Questions