Как условно представить контекстное меню SwiftUI?
Рассмотрим следующий код представления:
Text("Something")
.contextMenu {
// Some menu options
}
Это прекрасно работает. Что я хотел бы сделать: представить contextMenu через косвенное обращение к модификатору представления. Что-то вроде этого:
Text("Something")
.modifier(myContextMenu) {
// Some menu options
}
Почему: мне нужно выполнить некоторую логику внутри модификатора, чтобы условно отображать или не отображать меню. Я не могу определить для него правильную сигнатуру модификатора представления.
Есть еще один доступный модификатор contextMenu, который утверждает, что я могу условно представить для него контекстное меню. Попробовав это, это мне не помогает, потому что, как только я добавляю модификатор contextMenu в NavigationLink на iOS, жест касания перестает работать. В ответе ниже есть обсуждение.
Как представить контекстное меню с помощью модификатора представления?
3 ответа
Вот что я придумал. Не совсем устраивает, можно было бы и компактнее, но работает как положено.
struct ListView: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: ItemView(item: "Something")) {
Text("Something").modifier(withiOSContextMenu())
}.modifier(withOSXContextMenu())
}
}
}
}
struct withOSXContextMenu: ViewModifier {
func body(content: Content) -> some View {
#if os(OSX)
return content.contextMenu(ContextMenu {
ContextMenuContent()
})
#else
return content
#endif
}
}
struct withiOSContextMenu: ViewModifier {
func body(content: Content) -> some View {
#if os(iOS)
return content.contextMenu(ContextMenu {
ContextMenuContent()
})
#else
return content
#endif
}
}
func ContextMenuContent() -> some View {
Group {
Button("Click me") {
print("Button clicked")
}
Button("Another button") {
print("Another button clicked")
}
}
}
Вот демонстрация необязательного использования контекстного меню (протестировано с Xcode 11.2 / iOS 13.2)
struct TestConditionalContextMenu: View {
@State private var hasContextMenu = false
var body: some View {
VStack {
Button(hasContextMenu ? "Disable Menu" : "Enable Menu")
{ self.hasContextMenu.toggle() }
Divider()
Text("Hello, World!")
.background(Color.yellow)
.contextMenu(self.hasContextMenu ?
ContextMenu {
Button("Do something1") {}
Button("Do something2") {}
} : nil)
}
}
}
Что-то вроде этого?
Text("Options")
.contextMenu {
if (1 == 0) { // some if statements here
Button(action: {
//
}) {
Text("Choose Country")
Image(systemName: "globe")
}
}
}