Can someone please explain why the first time I tap on an item from the list, the selectedItem?.name
becomes nil
? The second time it shows the right item name correctly but not the first time, why?. I was expecting that to have a value even the first time since I'm setting it in the onTapGesture
method selectedItem = item
.
// model
struct Item: Identifiable{
var id = UUID()
var name:String
}
// SwiftUI
struct UpdateStateProperty: View {
var items:[Item] = [Item(name: "Oranges"),
Item(name: "Apples"),
Item(name: "Cookies") ]
@State private var presentView = false
@State private var selectedItem: Item?
var body: some View {
List{
ForEach(items){ item in
HStack{
Text(item.name)
}.onTapGesture {
selectedItem = item
presentView.toggle()
}
}
}
.sheet(isPresented: $presentView){
Text("\(selectedItem?.name)" as String)
}
}
}
Unfortunately, there's a known issue when you want to use @State
variables inside a closure passed to .sheet
.
(Seems Apple does not think this issue as a thing to be fixed.)
One possible workaround is declaring another view and pass the binding to it:
struct UpdateStateProperty: View {
var items:[Item] = [Item(name: "Oranges"),
Item(name: "Apples"),
Item(name: "Cookies") ]
@State private var presentView = false
@State private var selectedItem: Item?
var body: some View {
List{
ForEach(items){ item in
HStack{
Text(item.name)
}.onTapGesture {
selectedItem = item
presentView.toggle()
}
}
}
.sheet(isPresented: $presentView){
MySheetView(selectedItem: $selectedItem)
}
}
}
struct MySheetView: View {
@Binding var selectedItem: Item?
var body: some View {
Text("\(selectedItem?.name ?? "*nil*")")
}
}