I'm trying to create a popup menu, similar to .menu()
modifier that we have in SwiftUI. I managed to create the modifier and it is working fine.
Problem: The issue I have is that I am unable to have an overlay extend to the entire screen when the menu is displayed. Here's what I get when I try to overlay it (show in blue)
The reason for the problem is that I've a TabView
which is wrapped in a parent NavigationView
.
Menu modifier: Here's the modifier that I've created to show popup menus.
import SwiftUI
struct PopupMenu<MenuContent: View>: ViewModifier {
let menuContent: MenuContent
@Binding var isPresented: Bool
// Number crunching to limit menu size to 2/3rd of the screen
private let paddingRatio: CGFloat = 0.33
private let screenWidth = UIScreen.main.bounds.width
init(isPresented: Binding<Bool>, @ViewBuilder content: () -> MenuContent) {
_isPresented = isPresented
menuContent = content()
}
func body(content: Content) -> some View {
ZStack {
// The content to show menu on
content
if isPresented {
ZStack {
// Overlay to hide background - blue color is just to accentuate the issue
Color.blue
.onTapGesture {
isPresented.toggle()
}
// Actual menu rectangle
VStack {
HStack() {
Spacer(minLength: paddingRatio * screenWidth)
menuContent
.padding(regularPadding)
.background(
RoundedRectangle(cornerRadius: regularCorner)
.foregroundColor(.white)
.shadow(color: darkGray.opacity(0.3), radius: 24, x: -4, y: 12)
)
}
Spacer()
}
.padding(.trailing, regularPadding)
.padding(.top, 2)
}
}
}
}
}
extension View {
func popupMenu<MenuContent: View>(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> MenuContent) -> some View {
self.modifier(PopupMenu(isPresented: isPresented, content: content))
}
}