How to fade a UIVisualEffectView and/or UIBlurEffect in and out?

后端 未结 15 1003
故里飘歌
故里飘歌 2020-12-04 08:38

I want to fade a UIVisualEffectsView with a UIBlurEffect in and out:

var blurEffectView = UIVisualEffectView()
blurEffectView = UIVisualEffectView(effect: UI         


        
相关标签:
15条回答
  • 2020-12-04 09:24

    I make an uiview which alpha is 0 and add blurview as subview of that. So i can hide/show or rounding corners it with animation.

    0 讨论(0)
  • 2020-12-04 09:25

    The Apple documentation (currently) states...

    When using the UIVisualEffectView class, avoid alpha values that are less than 1.

    and

    Setting the alpha to less than 1 on the visual effect view or any of its superviews causes many effects to look incorrect or not show up at all.

    I believe some important context is missing here...

    I'd suggest that the intent is to avoid alpha values that are less than 1 for a persistent view. In my humble opinion this does not apply to the animation of a view.

    My point - I'd suggest that alpha values less than 1 are acceptable for animations.

    The terminal message states:

    UIVisualEffectView is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1.

    Reading this carefully, the effect will appear to be broken. My points on this being:

    • the apparent break only really matters for a view that is persistent - not changing;
    • a persistent / unchanging UIVisualEffect view with an alpha value less than 1 will not present as intended / designed by Apple; and
    • the message in the terminal is not an error, just a warning.

    To extend @jrturton's answer above that helped me solve my problem, I'd add...

    To fade out the UIVisualEffect use the following (Objective-C) code:

    UIView.animateWithDuration(1.0, animations: {
    //  EITHER...
        self.blurEffectView.effect = UIBlurEffect(nil)
    //  OR...
        self.blurEffectView.alpha = 0
    }, completion: { (finished: Bool) -> Void in
        self.blurEffectView.removeFromSuperview()
    } )
    

    I successfully use both methods: setting the effect property to nil and setting the alpha property to 0.

    Note that setting the effect to nil creates a "nice flash" (for want of a better description) at the end of the animation, while setting the alpha to 0 creates a smooth transition.

    (Let me know any syntax errors... I write in obj-c.)

    0 讨论(0)
  • 2020-12-04 09:30

    Usually, I only want to animate a blur when I'm presenting a view controller over the screen and want to blur the presenting view controller. Here's an extension that adds blur() and unblur() to a view controller in order to facilitate that:

    extension UIViewController {
    
       func blur() {
           //   Blur out the current view
           let blurView = UIVisualEffectView(frame: self.view.frame)
           self.view.addSubview(blurView)
           UIView.animate(withDuration:0.25) {
               blurView.effect = UIBlurEffect(style: .light)
           }
       }
    
       func unblur() {
           for childView in view.subviews {
               guard let effectView = childView as? UIVisualEffectView else { continue }
               UIView.animate(withDuration: 0.25, animations: {
                    effectView.effect = nil
               }) {
                   didFinish in
                   effectView.removeFromSuperview()
               }
           }
       }
    }
    

    You can of course make this more robust by letting the user choose the effect style, modify the duration, call something when the animation is completed, tag the added visual effect view in blur() to ensure it's the only one removed when you unblur(), etc., but I haven't found the need to do these things so far, since this tends to be a "fire and forget" type of operation.

    0 讨论(0)
  • 2020-12-04 09:31

    based on @cc's answer i modified his extension to blur a view

    extension UIView {
    
        func blur() {
            //   Blur out the current view
            let blurView = UIVisualEffectView(frame: self.bounds)
            self.addSubview(blurView)
            UIView.animate(withDuration:0.25) {
                blurView.effect = UIBlurEffect(style: .dark)
            }
        }
    
        func unblur() {
            for childView in subviews {
                guard let effectView = childView as? UIVisualEffectView else { continue }
                UIView.animate(withDuration: 2.5, animations: {
                    effectView.effect = nil
                }) {
                    didFinish in
                    effectView.removeFromSuperview()
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-04 09:32

    Just a workaround - put UIVisualEffectView into a container view and change alpha property for that container. That approach works perfectly for me on iOS 9. Seems it no longer works in iOS 10.

    0 讨论(0)
  • 2020-12-04 09:36

    You can take a snapshot of a static underlying view, and fade it in and out without touching the opacity of the blur view. Assuming an ivar of blurView:

    func addBlur() {
        guard let blurEffectView = blurEffectView else { return }
    
        //snapShot = UIScreen.mainScreen().snapshotViewAfterScreenUpdates(false)
        let snapShot = self.view.snapshotViewAfterScreenUpdates(false)
        view.addSubview(blurEffectView)
        view.addSubview(snapShot)
    
        UIView.animateWithDuration(0.25, animations: {
            snapShot.alpha = 0.0
        }, completion: { (finished: Bool) -> Void in
            snapShot.removeFromSuperview()
        } )
    }
    
    func removeBlur() {
        guard let blurEffectView = blurEffectView else { return }
    
        let snapShot = self.view.snapshotViewAfterScreenUpdates(false)
        snapShot.alpha = 0.0
        view.addSubview(snapShot)
    
        UIView.animateWithDuration(0.25, animations: {
            snapShot.alpha = 1.0
        }, completion: { (finished: Bool) -> Void in
            blurEffectView.removeFromSuperview()
            snapShot.removeFromSuperview()
        } )
    }
    
    0 讨论(0)
提交回复
热议问题