Alexander Ko
Alexander Ko

Reputation: 195

Swift blur effect is not dismissed when returning to main view

I want to show a subview, which is transperrent, therefore blur the main view controller. This works fine, but when returning to the main view controller, the blur stays - and it doesn't go to any section in the main view, like view did appear or popoverPresentationControllerDidDismissPopover.

I run this code to create the blur and show the subview:

if !UIAccessibilityIsReduceTransparencyEnabled() {
    self.view.backgroundColor = UIColor.clear

    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.extraLight)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView.frame = self.view.bounds
    blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    self.view.addSubview(blurEffectView)
}

let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PriceAlarmPopUp") as!  PriceAlarmPopupViewController
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)

popOverVC.didMove(toParentViewController: self)

When finishing the subview, I do:

self.view.removeFromSuperview()

Is there anything I do wrong? I tried already several solutions, but was not able to get rid of the blur subview.

Upvotes: 2

Views: 1346

Answers (5)

You can use protocols to solve this. I hope the example below helps.

class MainViewController: UIViewController, RemoveBlurViewDelegate {

//MARK: - Properties
private weak var blurView: UIView?

// MARK: - Navigation

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
    if segue.identifier == "SegueToPopverVc" {
        
        if let popOver = segue.destination.contents as? PriceAlarmPopupViewController {
            
            popOver.removeBlurDelegate = self
            
            // Adds the bluer Effect
            let blurEffect = UIBlurEffect(style: .extraLight)
            let blurEffectView = UIVisualEffectView(effect: blurEffect)
            blurEffectView.frame = self.view.bounds
            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            self.view.addSubview(blurEffectView)
            blurView = blurEffectView
        }
    }
}


//MARK: - Implentation of the RemoveBlurViewDelegate

func removeBluer() {
    blurView?.removeFromSuperview()
}

//MARK: - End of MAinViewController

}




//MARK: - Protocol to remove the blur from other VC

protocol RemoveBlurViewDelegate {
         func removeBluer()
  }

//MARK: - End of RemoveBlurViewDelegate protocol


//MARK: - PopupViewController
class PriceAlarmPopupViewController: UIViewController {


//MARK: - properties
var removeBlurDelegate: RemoveBlurViewDelegate?

//MARK: - PopupVieController life cycle

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    removeBlurDelegate?.removeBluer()
}

//MARK: - End of PriceAlarmPopupViewController

}

Upvotes: 0

solenoid
solenoid

Reputation: 1022

Set your blur effect to nil. It's even animatable if you wish (in fact the only proper way to animate out of a blurview)

        UIView.animate(withDuration: 0.95, delay: 0, options: .curveEaseIn, animations:  {() -> Void in
        self.blurView.effect = nil
        }, completion: {(finished:Bool) -> Void in       
        })

Upvotes: 1

NRitH
NRitH

Reputation: 13893

When the popup is dismissed, you have to remove the blur view, not self.view, i.e. blurEffectView.removeFromSuperview().

Upvotes: 1

Vasilii Muravev
Vasilii Muravev

Reputation: 3163

Keep weak reference for your blur view, and later remove it from superview:

class MyVC: UIViewController {

    private weak var blurView: UIView?

    func foo() {
        if !UIAccessibilityIsReduceTransparencyEnabled() {
            self.view.backgroundColor = UIColor.clear
            let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.extraLight)
            let blurEffectView = UIVisualEffectView(effect: blurEffect)
            blurEffectView.frame = self.view.bounds
            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            self.view.addSubview(blurEffectView)
            blurView = blurEffectView // HERE YOU SAVE WEAK REFERENCE
        }

        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PriceAlarmPopUp") as!  PriceAlarmPopupViewController
        self.addChildViewController(popOverVC)
        popOverVC.view.frame = self.view.frame
        self.view.addSubview(popOverVC.view)

        popOverVC.didMove(toParentViewController: self)
    }

    func fooDone() {
        blurView?.removeFromSuperview() // Blur view will be removed from sureview and automatically `blurView` becomes to `nil`
    }
}

If you want to hide it from another view controller, use closures:

class MyVC: UIViewController {
    func foo() {
        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PriceAlarmPopUp") as!  PriceAlarmPopupViewController
        self.addChildViewController(popOverVC)
        popOverVC.view.frame = self.view.frame
        if !UIAccessibilityIsReduceTransparencyEnabled() {
            self.view.backgroundColor = UIColor.clear
            let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.extraLight)
            let blurEffectView = UIVisualEffectView(effect: blurEffect)
            blurEffectView.frame = self.view.bounds
            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            self.view.addSubview(blurEffectView)
            popOverVC.userTappedCloseButtonClosure = { [weak blurEffectView] in
                blurEffectView?.removeFromSuperview()
            }
        }
        self.view.addSubview(popOverVC.view)
        popOverVC.didMove(toParentViewController: self)
    }
}

class PriceAlarmPopupViewController: UIViewController {
    public var userTappedCloseButtonClosure: (() -> Void)?

    @IBAction func closeButtonAction(_ sender: Any) {
        userTappedCloseButtonClosure?()
    }
}

Upvotes: 1

Phani Sai
Phani Sai

Reputation: 1233

Add tag to your view as shown bellow

let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.extraLight)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
        blurEffectView.tag = 100

    blurEffectView.frame = self.view.bounds
    blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    self.view.addSubview(blurEffectView)

Remove blurEffectView view with tag

self.view.viewWithTag(100)?.removeFromSuperview()

Upvotes: 0

Related Questions