1

I have this List view

List(expenses) { expense in
    ExpenseListItemView(expense: expense)
        .swipeActions {
            Button("Edit") {
                selectedExpenseId = expense.id
                showAddExpensePopup = true
            }.tint(.blue)
        }
    }
    .popover(isPresented: $showExpenseEditorPopup) {
        if let id = selectedExpenseId {
            ExpenseEditorScreen(expenseId: id)
        } else {
            ExpenseEditorScreen()
        }
    }
}

selectedExpenseId and showAddExpensePopup are both @State variables and selectedExpenseId is not getting updated and so I am always in the else case in the popover and can't edit an existing object

I know I can achieve this functionality by using the other .popover(item: ), I just want to understand what's happening in this case

Abdurakhmon
  • 2,813
  • 5
  • 20
  • 41
  • 1
    Use `popover(item:)` or use `.popover(isPresented: $showExpenseEditorPopup) { [selectedExpenseId] in` – jnpdx Apr 18 '23 at 20:46
  • 1
    See https://stackoverflow.com/questions/66162219/swiftui-switch-sheet-on-enum-does-not-work for example – jnpdx Apr 18 '23 at 20:46
  • 1
    "I just want to understand what's happening in this case" -- the content of the closure is evaluated before `selectedExpenseId` changes – jnpdx Apr 18 '23 at 22:57

1 Answers1

1

It's because you didn't read the @State in body anywhere so SwiftUI's dependency tracking didn't work (It only calls body when states are set for ones that are read). You can force it like this:

 .popover(isPresented: $showExpenseEditorPopup) { [selectedExpenseId] in
        if let id = selectedExpenseId {

Learn the details in Data Essentials in SwiftUI WWDC 2020 at 7:32.

malhal
  • 26,330
  • 7
  • 115
  • 133