Is There a Method to Blur a Background in Swiftui

Is there a method to blur a background in SwiftUI?

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

How can I have a Blur effect as a Background in SwiftUI?

In iOS 15 you can use Materials, like .ultraThinMaterial

.background(.ultraThinMaterial)

But from iOS 14 down, there is no SwiftUI way to achieve this, though it is possible to create an UIViewRepresentable and place it as a background.

Following code will create a UIViewRepresentable that you are able to use as a background: .systemUltraThinMaterial can be changed to any material

import SwiftUI
struct BlurView: UIViewRepresentable {
var style: UIBlurEffect.Style = .systemUltraThinMaterial
func makeUIView(context: Context) -> UIVisualEffectView {
return UIVisualEffectView(effect: UIBlurEffect(style: style))
}
func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
uiView.effect = UIBlurEffect(style: style)
}
}

View extension (optional):

extension View {
func backgroundBlurEffect() -> some View {
self.background(BlurView())
}
}

Then use on a view like a pop up.

.background(BlurView()) 

or if used like extension

.backgroundBlurEffect()

See image

SwiftUI - How can I blur the default background color of a view?

It is possible to apply blur directly to background only, like in the example below

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

blur button

How to blur background when another view is active?

The blur effect accumulates because VStack content is not determined as changed by SwiftUI rendering engine, so its cached rendered variant is used to next redraw.. and so on.

To fix this we need to mark VStack to refresh. Here is possible solution. Tested with Xcode 11.4 / iOS 13.4

VStack{
Button(action: {self.showWindow.toggle()}){
Text("Enable Blur")
.foregroundColor(.white)
.padding()
.background(Color.black)
.cornerRadius(5)
}
}.id(showWindow) // << here !!
.blur(radius: showWindow ? 5 : 0)

Is there a way to blur the background of a tapped element in SwiftUI?

Here is a demo of possible approach (as required behaviour not completely clear).

Tested with Xcode 11.4 / iOS 13.4

demo

struct DemoBlurImages: View {
let images = ["sun.max", "moon", "cloud"]

@State private var selected: String? = nil

var body: some View {
VStack {
ForEach(images, id: \.self) { name in
Image(systemName: name).resizable()
.onTapGesture {
if self.selected == name {
self.selected = nil
} else {
self.selected = name
}
}
.blur(radius: self.selected != nil && self.selected != name ? 10 : 0)
.scaleEffect(self.selected == name ? 1.2 : 1)
}
}
.animation(.spring())
.scaledToFit()
.frame(width: 100)
}
}

Create Background-blurred RoundedRectangle in SwiftUI

You can create another SwiftUI view:

struct BlurCircle: View {
var body: some View {
Blur()
.clipShape(Circle())
}
}

and use it like this:

struct ContentView: View {
var body: some View {
BlurCircle()
.frame(width: 100, height: 100)
}
}

Alternatively, you can just do:

struct ContentView: View {
var body: some View {
Blur()
.frame(width: 100, height: 100)
.clipShape(Circle())
}
}

If you don't want to do this outside the Blur struct, you can take a look at this answer:

  • How can UIVisualEffectView be used inside of a circle?

swiftui bring view to center and blur background after long press like messages app

You are looking for contextMenu(menuItems:). It shows those buttons you see, and automatically blurs the background content to focus the selected view.

Example:

struct ContentView: View {
var body: some View {
ScrollView {
LazyVStack(spacing: 30) {
ForEach(0 ..< 20) { _ in
Text(String(Int.random(in: 1 ... 100000000)))
.padding()
.contextMenu {
Button {
//
} label: {
Label("Reply", systemImage: "arrowshape.turn.up.left")
}

Button {
//
} label: {
Label("Copy", systemImage: "doc.on.doc")
}

Button {
//
} label: {
Label("Translate", systemImage: "arrow.left.arrow.right")
}

Button {
//
} label: {
Label("More…", systemImage: "ellipsis.circle")
}
}
}
}
}
}
}

Result:

Result



Related Topics



Leave a reply



Submit