返回主视图时不会消除快速模糊效果

Posted

技术标签:

【中文标题】返回主视图时不会消除快速模糊效果【英文标题】:Swift blur effect is not dismissed when returning to main view 【发布时间】:2017-07-13 15:36:05 【问题描述】:

我想显示一个透明的子视图,因此模糊了主视图控制器。这很好用,但是当返回到主视图控制器时,模糊仍然存在 - 它不会进入主视图中的任何部分,就像视图确实出现或 popoverPresentationControllerDidDismissPopover 一样。

我运行这段代码来创建模糊并显示子视图:

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)

完成子视图后,我会这样做:

self.view.removeFromSuperview()

我做错了什么吗?我已经尝试了几种解决方案,但无法摆脱模糊子视图。

【问题讨论】:

而不是删除视图控制器主视图,即 self.view remove blurEffectView.removeFromSuperview() 【参考方案1】:

为您的模糊视图保留弱引用,然后将其从超级视图中删除:

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`
    

如果你想对另一个视图控制器隐藏它,请使用闭包:

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?()
    

【讨论】:

感谢您的帮助。我试过了,并在删除他时在我的 popOverVC 中运行了 fooDone 函数。根据调试器,它进入了 fooDone 部分,但仍然没有消除模糊:( @AlexanderKo 你在主线程中运行了fooDone 吗?并在调用removeFromSuperview() 之前检查blurView 是否为nil 我在 PopupView 中尝试过::@IBAction func CloseButtonAction(_ sender: Any) self.view.removeFromSuperview() DispatchQueue.main.async let vc = KeepaDataViewController() vc.fooDone() -> 但不幸的是结果相同 @AlexanderKo 等等,所以CloseButtonAction(:)PriceAlarmPopupViewController 里面对吧? 完全正确。这是我作为 popOverVC 打开的弹出视图控制器。在那里我想按下关闭按钮,然后关闭 popupviewcontroller 并消除模糊。【参考方案2】:

当弹出窗口被关闭时,您必须删除模糊视图,而不是self.view,即blurEffectView.removeFromSuperview()

【讨论】:

但是我在哪里可以运行这段代码呢?我猜在主视图控制器中?但是在 PopupViewController 中运行 removeFromSuperView 后,它不会跳转到代码中的任何部分。 放到基础视图控制器的viewWillAppear().【参考方案3】:

将模糊效果设置为零。如果您愿意,它甚至可以制作动画(实际上是从模糊视图中制作动画的唯一正确方法)

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

【讨论】:

【参考方案4】:

将标签添加到您的视图中,如下所示

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)

移除带有标签的 blurEffectView 视图

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

【讨论】:

试过了,但不幸的是,没有积极的结果……我感觉有些东西没有按应有的方式运行。感谢您的帮助!

以上是关于返回主视图时不会消除快速模糊效果的主要内容,如果未能解决你的问题,请参考以下文章

快速为背景添加模糊效果

当用户触摸屏幕时,删除图像上的模糊效果[关闭]

渐变模糊效果

在顶部显示 UIView(对话框)时,iOS 对后面视图的模糊效果 [重复]

如何在 SwiftUI 中将模糊效果作为背景?

iOS,iOS9 +提供原生模糊视图效果?