Is there a method to blur a background in SwiftUI?

SwiftSwiftui

Swift Problem Overview


I'm looking to blur a view's background but don't want to have to break out into UIKit to accomplish it (eg. a UIVisualEffectView) I'm digging through docs and got nowhere, seemingly there is no way to live-clip a background and apply effects to it. Am I wrong or looking into it the wrong way?

Swift Solutions


Solution 1 - Swift

1. The Native SwiftUI way:

Just add .blur() modifier on anything you need to be blurry like:

Image("BG")
   .blur(radius: 20)

Blur Demo Note the top and bottom of the view

Note that you can Group multiple views and blur them together.


2. The Visual Effect View:

You can bring the prefect UIVisualEffectView from the UIKit:

VisualEffectView(effect: UIBlurEffect(style: .dark))

With this tiny struct:

struct VisualEffectView: UIViewRepresentable {
    var effect: UIVisualEffect?
    func makeUIView(context: UIViewRepresentableContext<Self>) -> UIVisualEffectView { UIVisualEffectView() }
    func updateUIView(_ uiView: UIVisualEffectView, context: UIViewRepresentableContext<Self>) { uiView.effect = effect }
}

VEV Demo


3. iOS 15: Materials

You can use iOS predefined materials with one line code:

.background(.ultraThinMaterial)

Demo

Solution 2 - Swift

I haven't found a way to achieve that in SwiftUI yet, but you can use UIKit stuff via UIViewRepresentable protocol.

struct BlurView: UIViewRepresentable {

    let style: UIBlurEffect.Style

    func makeUIView(context: UIViewRepresentableContext<BlurView>) -> UIView {
        let view = UIView(frame: .zero)
        view.backgroundColor = .clear
        let blurEffect = UIBlurEffect(style: style)
        let blurView = UIVisualEffectView(effect: blurEffect)
        blurView.translatesAutoresizingMaskIntoConstraints = false
        view.insertSubview(blurView, at: 0)
        NSLayoutConstraint.activate([
            blurView.heightAnchor.constraint(equalTo: view.heightAnchor),
            blurView.widthAnchor.constraint(equalTo: view.widthAnchor),
        ])
        return view
    }

    func updateUIView(_ uiView: UIView,
                      context: UIViewRepresentableContext<BlurView>) {

    }

}

Demo:

struct ContentView: View {

    var body: some View {
        NavigationView {
            ZStack {
                List(1...100) { item in
                    Rectangle().foregroundColor(Color.pink)
                }
                .navigationBarTitle(Text("A List"))
                ZStack {
                    BlurView(style: .light)
                        .frame(width: 300, height: 300)
                    Text("Hey there, I'm on top of the blur")
                        
                }
            }
        }
    }

}

I used ZStack to put views on top of it.

ZStack {
 // List
 ZStack {
    // Blurred View
    // Text
 }
}

And ends up looking like this:

enter image description here

Solution 3 - Swift

The simplest way is here by Richard Mullinix:

struct Blur: UIViewRepresentable {
	var style: UIBlurEffect.Style = .systemMaterial

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

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

Then just use it somewhere in your code like background:

    //...
    MyView()
        .background(Blur(style: .systemUltraThinMaterial))

Solution 4 - Swift

As mentioned by @mojtaba, it's very peculiar to see white shade at top of image when you set resizable() along with blur().

As simple trick is to raise the Image padding to -ve.

 var body: some View {
        
        return
            ZStack {
                
                Image("background_2").resizable()
                    .edgesIgnoringSafeArea(.all)
                    .blur(radius: 5)
                    .scaledToFill()
                    .padding(-20) //Trick: To escape from white patch @top & @bottom
                 

        }
  }

Result: SwiftUI Image blue trick

Solution 5 - Swift

@State private var amount: CGFLOAT = 0.0

var body: some View {
    VStack{
       Image("Car").resizable().blur(radius: amount, opaque: true)
    }
}

Using "Opaque: true" with blur function will eliminate white noise

Solution 6 - Swift

New in iOS 15 , SwiftUI has a brilliantly simple equivalent to UIVisualEffectView, that combines ZStack, the background() modifier, and a range of built-in materials.

ZStack {
    Image("niceLook")

    Text("Click me")
        .padding()
        .background(.thinMaterial)
}

You can adjust the “thickness” of your material – how much of the background content shines through – by using one of several material types. From thinnest to thickest, they are:

.ultraThinMaterial
.thinMaterial
.regularMaterial
.thickMaterial
.ultraThickMaterial

Solution 7 - Swift

Button("Test") {}
        .background(Rectangle().fill(Color.red).blur(radius: 20))

Solution 8 - Swift

There is a very useful but unfortunately private (thanks Apple) class CABackdropLayer

It draws a copy of the layers below, I found it useful when using blend mode or filters, It can also be used for blur effect

Code

open class UIBackdropView: UIView {

  open override class var layerClass: AnyClass {
	NSClassFromString("CABackdropLayer") ?? CALayer.self
  }
}

public struct Backdrop: UIViewRepresentable {

  public init() {}

  public func makeUIView(context: Context) -> UIBackdropView {
	UIBackdropView()
  }

  public func updateUIView(_ uiView: UIBackdropView, context: Context) {}
}

public struct Blur: View {

  public var radius: CGFloat
  public var opaque: Bool

  public init(radius: CGFloat = 3.0, opaque: Bool = false) {
	self.radius = radius
	self.opaque = opaque
  }

  public var body: some View {
	Backdrop()
	  .blur(radius: radius, opaque: opaque)
  }
}
Usage
struct Example: View {

  var body: some View {
    ZStack {
      YourBelowView()
   	  YourTopView()
        .background(Blur())
        .background(Color.someColor.opacity(0.4))
    }
  }
}

Source

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDarren TreatView Question on Stackoverflow
Solution 1 - SwiftMojtaba HosseiniView Answer on Stackoverflow
Solution 2 - SwiftMatteo PaciniView Answer on Stackoverflow
Solution 3 - Swiftcyber-botView Answer on Stackoverflow
Solution 4 - SwiftbyJeevanView Answer on Stackoverflow
Solution 5 - SwiftSheikh Wahab MahmoodView Answer on Stackoverflow
Solution 6 - SwiftSh_KhanView Answer on Stackoverflow
Solution 7 - SwiftFatemehView Answer on Stackoverflow
Solution 8 - SwiftДанил ВойдиловView Answer on Stackoverflow