Adding blur effect to background in swift - ios

I am setting a background image to view controller. But also i want to add blur effect to this background. How can I do this?
I am setting background with following code:
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "testBg")!)
I found on internet for blur imageview how can i implement this to my background?
var darkBlur = UIBlurEffect(style: UIBlurEffectStyle.Dark)
// 2
var blurView = UIVisualEffectView(effect: darkBlur)
blurView.frame = imageView.bounds
// 3
imageView.addSubview(blurView)

I have tested this code and it's working fine:
let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)
For Swift 3.0:
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)
For Swift 4.0:
let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)
Here you can see result:
Or you can use this lib for that:
https://github.com/FlexMonkey/Blurable

You can make an extension of UIImageView.
Swift 2.0
import Foundation
import UIKit
extension UIImageView
{
func makeBlurImage(targetImageView:UIImageView?)
{
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = targetImageView!.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] // for supporting device rotation
targetImageView?.addSubview(blurEffectView)
}
}
Usage:
override func viewDidLoad()
{
super.viewDidLoad()
let sampleImageView = UIImageView(frame: CGRectMake(0, 200, 300, 325))
let sampleImage:UIImage = UIImage(named: "ic_120x120")!
sampleImageView.image = sampleImage
//Convert To Blur Image Here
sampleImageView.makeBlurImage(sampleImageView)
self.view.addSubview(sampleImageView)
}
Swift 3 Extension
import Foundation
import UIKit
extension UIImageView
{
func addBlurEffect()
{
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // for supporting device rotation
self.addSubview(blurEffectView)
}
}
Usage:
yourImageView.addBlurEffect()
Addendum:
extension UIView {
/// Remove UIBlurEffect from UIView
func removeBlurEffect() {
let blurredEffectViews = self.subviews.filter{$0 is UIVisualEffectView}
blurredEffectViews.forEach{ blurView in
blurView.removeFromSuperview()
}
}
Swift 5.0:
import UIKit
extension UIImageView {
func applyBlurEffect() {
let blurEffect = UIBlurEffect(style: .light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(blurEffectView)
}
}

#AlvinGeorge should just use:
extension UIImageView{
func blurImage()
{
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] // for supporting device rotation
self.addSubview(blurEffectView)
}
}
usage:
blurredBackground.frame = self.view.bounds
blurredBackground.blurImage()
self.view.addSubview(self.blurredBackground)

U can also use CoreImage to create blurred image with dark effect
Make snapshot for image
func snapShotImage() -> UIImage {
UIGraphicsBeginImageContext(self.frame.size)
if let context = UIGraphicsGetCurrentContext() {
self.layer.renderInContext(context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
return UIImage()
}
Apply CoreImage Filters as u wish with
private func bluredImage(view:UIView, radius:CGFloat = 1) -> UIImage {
let image = view.snapShotImage()
if let source = image.CGImage {
let context = CIContext(options: nil)
let inputImage = CIImage(CGImage: source)
let clampFilter = CIFilter(name: "CIAffineClamp")
clampFilter?.setDefaults()
clampFilter?.setValue(inputImage, forKey: kCIInputImageKey)
if let clampedImage = clampFilter?.valueForKey(kCIOutputImageKey) as? CIImage {
let explosureFilter = CIFilter(name: "CIExposureAdjust")
explosureFilter?.setValue(clampedImage, forKey: kCIInputImageKey)
explosureFilter?.setValue(-1.0, forKey: kCIInputEVKey)
if let explosureImage = explosureFilter?.valueForKey(kCIOutputImageKey) as? CIImage {
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(explosureImage, forKey: kCIInputImageKey)
filter?.setValue("\(radius)", forKey:kCIInputRadiusKey)
if let result = filter?.valueForKey(kCIOutputImageKey) as? CIImage {
let bounds = UIScreen.mainScreen().bounds
let cgImage = context.createCGImage(result, fromRect: bounds)
let returnImage = UIImage(CGImage: cgImage)
return returnImage
}
}
}
}
return UIImage()
}

For Swift 3 (iOS 10.0 and 8.0)
var darkBlur:UIBlurEffect = UIBlurEffect()
if #available(iOS 10.0, *) { //iOS 10.0 and above
darkBlur = UIBlurEffect(style: UIBlurEffectStyle.prominent)//prominent,regular,extraLight, light, dark
} else { //iOS 8.0 and above
darkBlur = UIBlurEffect(style: UIBlurEffectStyle.dark) //extraLight, light, dark
}
let blurView = UIVisualEffectView(effect: darkBlur)
blurView.frame = self.view.frame //your view that have any objects
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurView)

This worked for me on Swift 5
let blurredView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurredView.frame = self.view.bounds
backgroundimage.addSubview(blurredView)

This one always keeps the right frame:
public extension UIView {
#discardableResult
public func addBlur(style: UIBlurEffect.Style = .extraLight) -> UIVisualEffectView {
let blurEffect = UIBlurEffect(style: style)
let blurBackground = UIVisualEffectView(effect: blurEffect)
addSubview(blurBackground)
blurBackground.translatesAutoresizingMaskIntoConstraints = false
blurBackground.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
blurBackground.topAnchor.constraint(equalTo: topAnchor).isActive = true
blurBackground.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
blurBackground.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
return blurBackground
}
}

You should always use .dark for style and add the following code to make it look cool
blurEffectView.backgroundColor = .black
blurEffectView.alpha = 0.4

This Code is Working Fine For me!
its for Swift 4.x
let blurEffect = UIBlurEffect(style: .ExtraLight)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.view.frame
self.view.insertSubview(blurEffectView, atIndex: 0)

In a UIView extension:
func addBlurredBackground(style: UIBlurEffect.Style) {
let blurEffect = UIBlurEffect(style: style)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = self.frame
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.addSubview(blurView)
self.sendSubviewToBack(blurView)
}

Found another way.. I use apple's UIImage+ImageEffects.
UIImage *effectImage = [image applyExtraLightEffect];
self.imageView.image = effectImage;

let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.backgroundColor = .black
blurEffectView.alpha = 0.5
blurEffectView.frame = topView.bounds
if !self.presenting {
blurEffectView.frame.origin.x = 0
} else {
blurEffectView.frame.origin.x = -topView.frame.width
}
blurEffectView.frame.origin.x = -topView.frame.width
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
UIView.animate(withDuration: 0.2, delay: 0.0, options: [.curveEaseIn]) {
if !self.presenting {
blurEffectView.frame.origin.x = -topView.frame.width
} else {
blurEffectView.frame.origin.x = 0
}
view.addSubview(blurEffectView)
} completion: { (status) in
}

Thanks to #Maruta
https://stackoverflow.com/a/56334283/16457129 for the answer If anyone else asks, you can reduce the blur effect with the background color of the view.
func drawBackgroundBlur() {
backgroundView.layer.cornerRadius = 27
// Here, you can increase the alpha value to increase the blur effect
backgroundView.backgroundColor = UIColor.white.withAlphaComponent(0.05)
let blurredView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurredView.frame = backgroundRewardsView.bounds
blurredView.layer.cornerRadius = 27
backgroundView.addSubview(blurredView)
}

Swift 5.7 - blur with custom radius
Usage example:
let view = UIImageView(image: bluredImage(view: superview!, radius: 1.5))
Extension:
extension UIView {
func bluredImage(view: UIView, radius: CGFloat = 1) -> UIImage {
let image = view.snapShotImage()
if let source = image.cgImage {
let context = CIContext(options: nil)
let inputImage = CIImage(cgImage: source)
let clampFilter = CIFilter(name: "CIAffineClamp")
clampFilter?.setDefaults()
clampFilter?.setValue(inputImage, forKey: kCIInputImageKey)
if let clampedImage = clampFilter?.value(forKey: kCIOutputImageKey) as? CIImage {
let explosureFilter = CIFilter(name: "CIExposureAdjust")
explosureFilter?.setValue(clampedImage, forKey: kCIInputImageKey)
explosureFilter?.setValue(-1.0, forKey: kCIInputEVKey)
if let explosureImage = explosureFilter?.value(forKey: kCIOutputImageKey) as? CIImage {
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(explosureImage, forKey: kCIInputImageKey)
filter?.setValue("\(radius)", forKey:kCIInputRadiusKey)
if let result = filter?.value(forKey: kCIOutputImageKey) as? CIImage {
let bounds = UIScreen.main.bounds
let cgImage = context.createCGImage(result, from: bounds)
let returnImage = UIImage(cgImage: cgImage!)
return returnImage
}
}
}
}
return UIImage()
}
private func snapShotImage() -> UIImage {
UIGraphicsBeginImageContext(self.frame.size)
if let context = UIGraphicsGetCurrentContext() {
self.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
return UIImage()
}
}

Related

How can I make the Navigation Bar transparent?

How can I make this part of the app (the Navigation Bar) translucent? I don't want it to be fully transparent, I want it to show the website content's colours and be blurred.
Link with screenshot: iPhone 12 simulator with Navigation Bar Opaque
I have looked at tens of possibilities and none worked:
let bounds = self.navigationController?.navigationBar.bounds as CGRect!
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
visualEffectView.frame = bounds
self.navigationController?.navigationBar.addSubview(visualEffectView)
self.navigationController.navigationBar.translucent = YES;
I also tried:
let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = (self.navigationController?.navigationBar.bounds)!
self.navigationController?.navigationBar.addSubview(blurEffectView)darkUIBlurEffect.Style
Also this:
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) //UIImage.init(named: "transparent.png")
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = .clear
And this:
self.navigationController?.navigationBar.isTranslucent = true
I also tried using the Main.storyboard's Attributes Inspector and ticked Translucent.
Attributes Inspector tab on Navigation Bar in Main.storyboard
No method worked. What should I do?
Try this:
extension UIViewController {
func blurNav(withAlpha alpha:CGFloat = 1.0 ) {
let statusBarHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
let rect = navigationController?.navigationBar.bounds.insetBy(dx: 0, dy: -(statusBarHeight)).offsetBy(dx: 0, dy: -(statusBarHeight)) ?? .zero
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurView.frame = rect
blurView.isUserInteractionEnabled = false
blurView.alpha = alpha
blurView.layer.zPosition = -1
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.addSubview(blurView)
navigationController?.navigationBar.sendSubviewToBack(blurView)
}
}
Usage:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
blurNav(withAlpha: 0.8)
}

Blur effect on view background

I have this extension, and I was hoping for a blur background, where I can see blur through the view:
import Foundation
import UIKit
extension UIView
{
func addBlurEffect()
{
if !UIAccessibilityIsReduceTransparencyEnabled() {
self.backgroundColor = UIColor.clear
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.addSubview(blurEffectView)
} else {
self.backgroundColor = UIColor.white
}
}
}
Then I use it like this:
let v = UIView(frame: self.view.frame)
v.addBlurEffect()
self.view.addSubview(v)
But I can not see anything under the view?
Add this framework to your project.
Add transparent view over your background and setup blur (view Readme on github)
Preview

Add uiview to be the background view

I have the following blur view, that I would like to be the background view. The problem is that it becomes the first view, hiding underneath labels/cells etc. I tought that self.sendSubview(toBack: blurEffectView) would do just that - do you know why? :
Update: also tried: self.insertSubview(blurEffectView, belowSubview: self)
import Foundation
import UIKit
extension UIView
{
func addBlurEffect()
{
if !UIAccessibilityIsReduceTransparencyEnabled() {
self.backgroundColor = UIColor.clear
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.addSubview(blurEffectView)
self.sendSubview(toBack: blurEffectView)
} else {
self.backgroundColor = UIColor.white
}
}
}
It turns out that it is only when using UIViewController or UItableView.
import Foundation
import UIKit
extension UIView
{
func addBlurEffect()
{
if !UIAccessibilityIsReduceTransparencyEnabled() {
self.backgroundColor = UIColor.clear
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
if (self is UICollectionView){
(self as! UICollectionView).backgroundView = blurEffectView
}else{
self.addSubview(blurEffectView)
self.insertSubview(blurEffectView, belowSubview: self)
}
} else {
self.backgroundColor = UIColor.white
}
}
}

Background image not loading on device

I have this code that places the image in the background and applies a blur effect:
let effect = UIBlurEffect(style: .Dark)
override func viewDidLoad() {
let backgroundView = UIView(frame: view.bounds)
backgroundView.autoresizingMask = resizingMask
backgroundView.addSubview(self.buildImageView())
backgroundView.addSubview(self.buildBlurView())
tableView.backgroundColor = UIColor.clearColor()
tableView.backgroundView = backgroundView
tableView.separatorEffect = UIVibrancyEffect(forBlurEffect: effect)
}
func buildImageView() -> UIImageView {
let imageView = UIImageView(image: UIImage(named: "pexels-photo"))
imageView.frame = view.bounds
imageView.autoresizingMask = resizingMask
return imageView
}
func buildBlurView() -> UIVisualEffectView {
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = view.bounds
blurView.autoresizingMask = resizingMask
return blurView
}
When I run this in the simulator it loads fine. But when I test it on an iPhone 6 it just loads a black background.
Any help on how to solve this problem would be appreciated.
Try below code tested in Xcode 8 it worked. Code tested as a UIView..
**Answer 1:** From your code
// Change bLurView Style to .dark or .extraLight If you want
let effect = UIBlurEffect(style: .light)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let backgroundView = UIView(frame: view.bounds)
// backgroundView.autoresizingMask = resizingMask
view.addSubview(self.buildImageView())
view.addSubview(self.buildBlurView())
/////Code tested in UIView not in tableView.It won't do any difference just let you know///////
tableView.backgroundColor = UIColor.clearColor()
// tableView.backgroundView = backgroundView
tableView.separatorEffect = UIVibrancyEffect(forBlurEffect: effect)
/////////////////////////////////////////////////////////////////////
}
func buildImageView() -> UIImageView {
let imageView = UIImageView(image: UIImage(named: "pexels-photo"))
imageView.frame = view.bounds
// imageView.autoresizingMask = resizingMask
return imageView
}
func buildBlurView() -> UIVisualEffectView {
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = view.bounds
// blurView.autoresizingMask = resizingMask
return blurView
}
Answer 2:
override func viewDidLoad() {
super.viewDidLoad()
// Add a background view to the table view
let backgroundImage = UIImage(named: "your image file")
let imageView = UIImageView(image: backgroundImage)
self.tableView.backgroundView = imageView
imageView.contentMode = .ScaleAspectFit
// no lines where there aren't cells
tableView.tableFooterView = UIView(frame: CGRectZero)
//set background colour to light color or clear color to get a transparent look
tableView.backgroundColor = .lightGrayColor()
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = imageView.bounds
imageView.addSubview(blurView)
}
If we want to make the table view cells totally transparent you can just set their background color to clear:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.backgroundColor = UIColor(white: 1, alpha: 0.5) // UIcolor.clear
}
output of the above code as below....

How to remove blur subview from super view

I need to blur screen when alert is shown, so I googled the function, which blurs the screen
it looks like
var effectView: UIVisualEffectView!
func addBlur() {
var effect = UIBlurEffect(style: UIBlurEffectStyle.Light)
effectView = UIVisualEffectView(effect: effect)
effectView.frame = CGRectMake(0, 0, self.view.bounds.width, self.view.bounds.height)
view.addSubview(effectView)
}
I want to remove the blur after user dismissed the alert and I come up with the such function
func removeBlur() {
effectView.view.removeFromSuperview()
}
but it doesn't work, says UIVisualEffectView does not have a member named "view"
How to fix it?
func removeBlur() {
effectView.removeFromSuperview()
}
You can also try this way:
func blureffect() {
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)
}

Resources