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

后端 未结 15 1004
故里飘歌
故里飘歌 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:36

    Improving @Tel4tel and @cc response, here is an extension with parameters and a brief explanation.

    extension UIView {
    
        // Perform a blur animation in the whole view
        // Effect tone can be .light, .dark, .regular...
        func blur(duration inSeconds: Double, effect tone: UIBlurEffectStyle) {
            let blurView = UIVisualEffectView(frame: self.bounds)
            self.addSubview(blurView)
            UIView.animate(withDuration: inSeconds) {
                blurView.effect = UIBlurEffect(style: tone)
            }
        }
    
        // Perform an unblur animation in the whole view
        func unblur(duration inSeconds: Double) {
            for childView in subviews {
                guard let effectView = childView as? UIVisualEffectView else { continue 
            }
                UIView.animate(withDuration: inSeconds, animations: {
                    effectView.effect = nil
                }){
                    didFinish in effectView.removeFromSuperview()
                }
            }
        }
    }
    

    Then you can use it like: view.blur(duration: 5.0, effect: .light) or view.unblur(duration: 3.0)

    Remember to NOT use it in viewDidLoad() as it will override the animation. Also, when running on a Simulator, turn the graphics to the Higher level to be able to see the animation (Debug > Graphics Quality Override > High Quality).

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

    Here is the solution that I ended up which works on both iOS10 and earlier versions using Swift 3

    extension UIVisualEffectView {
    
        func fadeInEffect(_ style:UIBlurEffectStyle = .light, withDuration duration: TimeInterval = 1.0) {
            if #available(iOS 10.0, *) {
                let animator = UIViewPropertyAnimator(duration: duration, curve: .easeIn) {
                    self.effect = UIBlurEffect(style: style)
                }
    
                animator.startAnimation()
            }else {
                // Fallback on earlier versions
                UIView.animate(withDuration: duration) {
                    self.effect = UIBlurEffect(style: style)
                }
            }
        }
    
        func fadeOutEffect(withDuration duration: TimeInterval = 1.0) {
            if #available(iOS 10.0, *) {
                let animator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
                    self.effect = nil
                }
    
                animator.startAnimation()
                animator.fractionComplete = 1
            }else {
                // Fallback on earlier versions
                UIView.animate(withDuration: duration) {
                    self.effect = nil
                }
            }
        }
    
    }
    

    You can also check this gist to find an example usage.

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

    I ended up with the following solution, using separate animations for the UIVisualEffectView and the contents. I used the viewWithTag() method to get a reference to the UIView inside the UIVisualEffectView.

    let blurEffectView = UIVisualEffectView()
    // Fade in
    UIView.animateWithDuration(1) { self.blurEffectView.effect = UIBlurEffect(style: .Light) }    
    UIView.animateWithDuration(1) { self.blurEffectView.viewWithTag(1)?.alpha = 1 }
    // Fade out
    UIView.animateWithDuration(1) { self.blurEffectView.effect = nil }    
    UIView.animateWithDuration(1) { self.blurEffectView.viewWithTag(1)?.alpha = 0 }
    

    I would prefer the single animation changing the alpha, but this avoids the error and seems to work just as well.

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题