4

I need to show a view above all views based upon certain conditions, no matter what the top view is. I am trying the following code:

    struct TestView<Presenting>: View where Presenting: View {
    
        /// The binding that decides the appropriate drawing in the body.
        @Binding var isShowing: Bool
        /// The view that will be "presenting" this notification
        let presenting: () -> Presenting
    
        var body: some View {
    
            GeometryReader { geometry in
                ZStack(alignment: .top) {
                    self.presenting()
    
                    HStack(alignment: .center) {
                        Text("Test")
                    }
                    .frame(width: geometry.size.width - 44,
                           height: 58)
                    .background(Color.gray.opacity(0.7))
                    .foregroundColor(Color.white)
                    .cornerRadius(20)
                    .transition(.slide)
                    .opacity(self.isShowing ? 1 : 0)
                }
            }
        }
    }

extension View {
    func showTopView(isShowing: Binding<Bool>) -> some View {
        TestView(isShowing: isShowing,
                               presenting: { self })
    }    
}

struct ContentView: View {
   @State var showTopView = false
   NavigationView {
            ZStack {
                content
            }
        }
        .showTopView(isShowing: $showTopView)

}

Now this is working fine in case of the views being pushed. But I am not able to show this TopView above the presented view.

Any help is appreciated!

Shivani Bajaj
  • 996
  • 10
  • 23
  • Does this answer your question https://stackoverflow.com/a/63259094/12299030? – Asperi Sep 02 '21 at 15:11
  • No, it does not @Asperi. I need a view to be shown on top, without considering what the current top view is, is the top view presented or pushed etc. It's like showing a loader on top of all views. – Shivani Bajaj Sep 02 '21 at 15:17

1 Answers1

-4

Here is a way for your goal, you do not need Binding, just use let value.

enter image description here

struct ContentView: View {
    
    @State private var isShowing: Bool = Bool()
    
    var body: some View {
        
        CustomView(isShowing: isShowing, content: { yourContent }, isShowingContent: { isShowingContent })
        
    }
    
    var yourContent: some View {
        
        NavigationView {
            
            VStack(spacing: 20.0) {
                
                Text("Hello, World!")
                
                Button("Show isShowing Content") { isShowing = true }
                
            }
            .navigationTitle("My App")
            
        }
        
    }
    
    var isShowingContent: some View {
        
        ZStack {
            
            Color.black.opacity(0.5).ignoresSafeArea()
            
            VStack {
                
                Spacer()
                
                Button("Close isShowing Content") { isShowing = false }
                    .foregroundColor(.white)
                    .padding()
                    .frame(maxWidth: .infinity)
                    .background(Color.blue.cornerRadius(10.0))
                    .padding()
                
            }
            
        }
        
    }
    
}

struct CustomView<Content: View, IsShowingContent: View>: View {
    
    let isShowing: Bool
    @ViewBuilder let content: () -> Content
    @ViewBuilder let isShowingContent: () -> IsShowingContent
    
    var body: some View {
        
        Group {
            
            if isShowing { ZStack { content().blur(radius: isShowing ? 5.0 : 0.0); isShowingContent() } }
            else { content() }
 
        }
        .animation(.default, value: isShowing)
        
    }
}
ios coder
  • 1
  • 4
  • 31
  • 91
  • it is not working in case of the presented view. Nothing is shown above the presented view. – Shivani Bajaj Sep 02 '21 at 16:12
  • Yes, I tried your code. Please try to present something with sheet and you will see that custom view is never shown above sheet. – Shivani Bajaj Sep 02 '21 at 16:18
  • https://stackoverflow.com/questions/59277120/overlay-swiftui-view-over-all-other-views-including-sheets This is the question I want answer for actually – Shivani Bajaj Sep 02 '21 at 16:23
  • With my answer you do not need to use sheet! My code is sheet! – ios coder Sep 02 '21 at 16:54
  • @ioscoder is it possible that the view is on top of elements in the navigationbar too? When I tried only the Title was covered but not the rest of the bar. – buleva Oct 07 '22 at 09:47