Here’s the code
import SwiftUI
struct MyView: View {
@State private var Items = ["Apple", "Microsoft", "Google"]
@State private var presentSheet = Bool()
var body: some View {
NavigationStack {
List {
ForEach(Items) { item in
Text(item)
.swipeActions(edge: .leading) {
Button("Show", systemImage: "eye" {
presentSheet.toggle
}
.tint(Color.yellow)
}
.sheet(isPresented: $presentSheet) {
Text(item)
}
}
}
.navigationTitle("MyView")
}
}
}
The sheet only shows the last item in the array, when it should show the item that opened the sheet
I know I’m stupid, but I’m currently learning SwiftUI, and I’ve done it for over a year now
I tried making a sheet view that only displays the text you selected
I was expecting it to show the single item, but instead just showed the last item in the array
2
Answers
Instead of
presentSheet
, useselectedItem
to use.sheet(item: $selectedItem)
. I added the@MainActor
annotation for safety reasons, and you should use it, too. If you compile it with Swift 6, you will get a warning that you should use@retroactive
(SE-0364) to conformString
toIdentifiable
.Downvoted because your code contains too many compilation errors, but here’s how to go about it:
The code as you had it couldn’t work, because the sheet doesn’t show the item at the time the ForEach loop runs. It shows some content at the time the button is pressed (or, whatever item was in the loop at the moment the modifier was attached).
To fix it, have the button set a state with the value of the item and read the state when the sheet opens. To keep it clean, since in this case, the state is a non-optional string, clear the state when the sheet is dismissed.
This will be easier to understand if the code is restructured to have the sheet modifier outside the loop, since there is no need for each array item to have its own sheet modifier if they all read from the same shared state value anyway: