3

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.

enter image description here

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))
    }
}
Siddharth Kamaria
  • 1,832
  • 2
  • 12
  • 27

1 Answers1

1

So it's apparent that you have a NavigationView. So in that case, use .overlay(popupMenu()) to overlay the menu over the existing NavigationView

for example,

NavigationView {
    //Some content
}
.overlay(popup(_,_))

and in you popOver View, make sure to add the .ignoresSafeArea() to the Color view as follows

Color.blue
   .ignoresSafeArea()
   .onTapGesture {
       isPresented.toggle()
    }

Visal Rajapakse
  • 1,254
  • 1
  • 6
  • 12