I would like to add Menu
in the cells of my list but this causes a strange behavior when I want to open the sheet view.
I get the following message:
[Presentation] Attempt to present <TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x1620b0800> on <TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier_: 0x161811800> (from <TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier_: 0x161811800>) which is already presenting <_UIContextMenuActionsOnlyViewController: 0x16051de40>.
I feel like the sheet view wants to open at the same time as the menu. How can I solve the problem?
Here is an example code that illustrates my problem:
struct Item: Identifiable{
let id: Int
let marque: String
let reference: String
}
struct ContentView: View {
@State var items = [Item(id: 1, marque: "Schneider", reference: "123333"), Item(id: 2, marque: "Siemens", reference: "1234444"), Item(id: 3, marque: "Beck", reference: "1233"), Item(id: 4, marque: "Aron", reference: "133449")]
@State private var selectedItem: Item?
var body: some View {
List {
ForEach(items, id: \.id) { item in
HStack {
Text(item.marque)
Spacer()
Menu(content: {
Button("Edit") {}
Button("Delete") {}
}, label: {
Image(systemName: "ellipsis.circle")
})
}
.onTapGesture {
self.selectedItem = item
}
}
}
.sheet(item: $selectedItem) { item in
VStack{
Text(item.marque)
Text(item.reference)
}
}
}
}
CodePudding user response:
Yes, sheet is trying to present at the same time as Menu, as we have the TapGesture
on the HStack
which contains both the row
and the Menu
.
What is happening behind the scene? :-
- When we tap the ellipse (
Menu
), SwiftUI will try to present the Menu. - But as we also have the
Tap Gesture
over theRow
, it will update theselectedItem
to item. - And as the
selectedItem
updates, as it is binding to the sheet, SwiftUI will then also try to present sheet. - And the error log prints in the console:
“Attempt to present which is already presenting”
. It tells you that asSelf
which is already presenting aMenu
and therefor can not present the sheet.
So in order to fix this, let’s update our ViewTree. We will keep the Text and Menu in different stack and only add gesture to the text (Row
).
List {
ForEach(items, id: \.id) { item in
HStack {
HStack {
Text(item.marque)
Spacer()
}
.contentShape(Rectangle())
.onTapGesture {
self.selectedItem = item
}
Menu(content: {
Button("Edit") {}
Button("Delete") {}
}, label: {
Image(systemName: "ellipsis.circle")
})
}
}
}
.sheet(item: $selectedItem) { item in
VStack{
Text(item.marque)
Text(item.reference)
}
}
This way tapping the Menu
will not update the selectedItem
property.