8

I need to pass a parameter calledFrom to a Sheet in SwiftUI.
Strangely, the parameter is not used on the first call, but it works on the following ones.

import SwiftUI

struct ContentView: View {
    @State var showSheet = false
    @State var calledFrom = -1
    
    var body: some View {
        ForEach((1...4), id: \.self) { i in
            getButton(i)
        }
        .sheet(isPresented: $showSheet) { Dialog(calledFrom: calledFrom) }
        .padding()
    }
    
    func getButton(_ i : Int) -> some View {
        return Button("\(i)"){print("Button \(i) pressed"); calledFrom = i; showSheet = true }
    }
}

struct Dialog: View {
  var calledFrom : Int
  @Environment(\.presentationMode) private var presentationMode
  var body: some View {
    VStack{
      Text("Called from Button \(calledFrom)")
        Button("close"){presentationMode.wrappedValue.dismiss()}
    }
    .padding()
  }
}
mica
  • 3,898
  • 4
  • 34
  • 62
  • 1
    Common issue in iOS 14. You need to use `sheet(item:)` instead of `sheet(isPresented:)`. See: https://stackoverflow.com/questions/66190082/state-var-not-updated-as-expected-in-lazyvgrid and https://stackoverflow.com/questions/66162219/swiftui-switch-sheet-on-enum-does-not-work – jnpdx Apr 03 '21 at 22:39

1 Answers1

11

You have to use sheet(item:) to get the behavior you're looking for. In iOS 14, the sheet view is calculated before the @State changes:


struct ActiveItem : Identifiable {
    var calledFrom: Int
    var id: Int { return calledFrom }
}

struct ContentView: View {
    @State var activeItem : ActiveItem?
    
    var body: some View {
        ForEach((1...4), id: \.self) { i in
            getButton(i)
        }
        .sheet(item: $activeItem) { item in
            Dialog(calledFrom: item.calledFrom)
        }
        .padding()
    }
    
    func getButton(_ i : Int) -> some View {
        return Button("\(i)"){
            print("Button \(i) pressed");
            activeItem = ActiveItem(calledFrom: i)
        }
    }
}
jnpdx
  • 45,847
  • 6
  • 64
  • 94