Search code examples
iosswiftuiimageviewuivisualeffectviewuiblureffect

Setting a UIImageView to an initial state of blurred


I'm attempting to initially blur a background image on a UIViewController. When an @IBAction is called, I'd like to unblur backgroundImage. I can get the image to initially blur, but I can't get rid of the blur if I initially blur it. However, if I don't initially blur backgroundImage, my method works as desired by toggling between a blurred and unblurred image.

These are the relevant variables on my UIViewController class.

@IBOutlet weak var backgroundImage: UIImageView!
// I also leave this hanging around so I can add/remove it as needed
var blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))

When the view loads, I'd initially like backgroundImage to have a UIVisualEffectView over it. I initially tried to call toggleBlurView in viewDidLoad, but the display of the UIBlurEffect was off, so I added the code for toggleBlurView in viewDidLayoutSubviews, which fixed that problem.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // if I comment this out, the toggleBlurView() method works as desired
    toggleBlurView()
}

Here's my toggleBlurView method.

func toggleBlurView() {
    // if there's a blurView, remove it...
    if blurView.isDescendant(of: backgroundImage) {
        blurView.removeFromSuperview()
    } 
    // otherwise, add blurView to backgroundImage
    else {
        blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
        blurView.frame = backgroundImage.bounds
        backgroundImage.addSubview(blurView)
    }
}

I have an @IBAction that, when called, also runs the toggleBlurView method.

@IBAction func playFrequency(_ sender: UIButton) {
    // do stuff
    toggleBlurView()
}

My code does not crash, but I can't get the desired results. I'm not sure if I've found a bug or I'm doing something wrong. I'm wagering the latter. Thank you for reading and I welcome suggestions how to set an image to an initial state of blurred.


Solution

  • I got the following code working as you want it to. I changed up the toggleBlurView function so it's a little more flexible, but this shouldn't affect the functionality.

    //
    //  ViewController.swift
    //  tableviewheader-test
    //
    //  Created by Forest Kunecke on 3/29/17.
    //  Use this code for freeeeee!!!!  Free as in free beer!!
    //
    
    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var myImage: UIImageView!
        var blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            toggleBlurView(myImage)
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
        @IBAction func toggleBlur(_ sender: Any) {
            toggleBlurView(myImage)
        }
    
        func toggleBlurView(_ imageView: UIImageView) {
            // if there's a blurView, remove it...
            if blurView.isDescendant(of: imageView) {
                blurView.removeFromSuperview()
            }
                // otherwise, add blurView to backgroundImage
            else {
                blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
                blurView.frame = imageView.bounds
                imageView.addSubview(blurView)
            }
        }
    
    }
    

    Here is a screenshot of my storyboard:

    screenshot of toggle image storyboard