UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SwiftUI Popover background with Material.

Forums > SwiftUI

I'm trying to create a SwiftUI Popover with a translucent material(regular, thin or ultra thin) background . To show up some vibrancy of the content behind to the Popover content.

The System always adding a default view behind the popover. hence my material not reflcting on the original content.

Any thoughts?

1      

I assume you are using the .sheet or similar? I do not think that you can change this as it a View. So you may have to do your own. This may work appated from Majid Jabrayilov (twitter @mecid) First make a SwiftUI file (I called it CustomPopOverView) and change it to this

struct CustomPopOverView<Content: View>: View {
    @Binding var isPresented: Bool
    @GestureState private var translation: CGFloat = 0

    let maxHeight: CGFloat
    let minHeight: CGFloat
    let content: Content

    init(isPresented: Binding<Bool>, maxHeight: CGFloat, @ViewBuilder content: () -> Content) {
        self.minHeight = maxHeight * 0.0
        self.maxHeight = maxHeight
        self.content = content()
        self._isPresented = isPresented
    }

    private var offset: CGFloat {
        isPresented ? 0 : maxHeight - minHeight
    }

    private var indicator: some View {
        RoundedRectangle(cornerRadius: 10)
            .fill(Color.secondary)
            .frame(width: 60, height: 6)
            .onTapGesture {
                isPresented.toggle()
            }
            .accessibility(label: Text("Close"))
            .accessibility(addTraits: .isButton)
    }

    var body: some View {
        GeometryReader { geometry in
            VStack(spacing: 0) {
                indicator
                    .padding()
                content
            }
            .frame(width: geometry.size.width, height: maxHeight, alignment: .top)
            .background(.ultraThinMaterial) // <- Change this for the background color
            .cornerRadius(16)
            .frame(height: geometry.size.height, alignment: .bottom)
            .offset(y: max(offset + translation, 0))
            .animation(.spring(), value: isPresented)
            .gesture(
                DragGesture().updating($translation) { value, state, _ in
                    state = value.translation.height
                }.onEnded { value in
                    let snapDistance = self.maxHeight * 0.25
                    guard abs(value.translation.height) > snapDistance else { return }
                    isPresented = value.translation.height < 0
                }
            )
        }
        .ignoresSafeArea()
    }
}

Then in the call View add it in a ZStack

struct ContentView: View {
    @State private var showingPopOver = false

    var body: some View {
        ZStack {
            Color.red
                .ignoresSafeArea()

            Button("Show PopOver") {
                showingPopOver.toggle()
            }
            .buttonStyle(.borderedProminent)

            CustomPopOverView(isPresented: $showingPopOver, maxHeight: 500) {
                Text("Pop Over") // <- Add the view you want here
            }
        }
    }
}

1      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.