Search code examples
swiftswiftuiuikituinavigationbarswiftui-navigationview

My two attempts at getting a blurred background for a navigation title in SwiftUI are not working


Beginner here making a simple todo list, but trying to get a blurred background only for the navigation title. I'm trying to do this with and without a UIViewRepresentable struct. Here is my method without the UIViewRepresentable struct.

"""

struct ContentView: View {

init() {
    let appearance = UINavigationBarAppearance()

    appearance.backgroundEffect = UIBlurEffect(style: .regular)

    UINavigationBar.appearance().standardAppearance = appearance        
    UITableView.appearance().backgroundColor = .clear
}

var body: some View {
    
        VStack {
            GeometryReader { geometry in
            VStack {
                List {
                    ListEntry()
                }
                .opacity(0.8)
                .frame(height: geometry.size.height*(4/5))
            }
            VStack {
                // empty for now
            }
            }
        }
        .background(LeavesBackgroundView())
        .navigationTitle(Text("Monday, Apr 26"))
        .navigationBarItems(trailing: Image(systemName: "gear"))
}

}

"""

..now with the UIViewRepresentable struct:

"""

struct theBlurView: UIViewRepresentable {

@State var style: UIBlurEffect.Style = .systemMaterial

func makeUIView(context: Context) -> UIVisualEffectView {
    let view = UIVisualEffectView(effect: UIBlurEffect(style: style))
    return view
}

func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
    uiView.effect = UIBlurEffect(style: style)
}

}

struct ContentView: View {

init() {
    let appearance = UINavigationBarAppearance()

    appearance.backgroundEffect = theBlurView(style: .regular) // error right here

    UINavigationBar.appearance().standardAppearance = appearance       
    UITableView.appearance().backgroundColor = .clear
}

var body: some View {
    
        VStack {
            GeometryReader { geometry in
            VStack {
                List {
                    ListEntry()
                }
                .opacity(0.8)
                .frame(height: geometry.size.height*(4/5))
            }
            VStack {
                // empty for now
            }
            }
        }
        .background(LeavesBackgroundView())
        .navigationTitle(Text("Monday, Apr 26"))
        .navigationBarItems(trailing: Image(systemName: "gear"))
}

}

"""

In the second case, I get the error "Cannot assign value of type 'theBlurView' to type 'UIBlurEffect?'", but I cannot figure out a way to get them to be the same type. In the first case, I get no error, but I get a white opaque navigation title background.

In both cases, I get this this

where the navigation title background is white. I've also tried different material styles (.dark, .light, .systemChromeMaterial, etc) and nothing makes it blurry.

This is the kind of blur I'm trying to get

Can somebody please point me in the right direction?


Solution

  • If you accept a third party library:

    1. Install SwiftUIX
    2. Make blur with few lines of code by modify your NavBar .background(VisualEffectBlurView(blurStyle: .systemThinMaterial)) and dont forget import SwiftUIX befor using.