Reputation: 195
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
Reputation: 21
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
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
Reputation: 13893
When the popup is dismissed, you have to remove the blur view, not self.view
, i.e. blurEffectView.removeFromSuperview()
.
Upvotes: 1
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
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