如何淡入和淡出UIVisualEffectView和/或UIBlurEffect?

Lin*_*rth 90 fade ios swift uiblureffect uivisualeffectview

我想淡入带有UIBlurEffect的UIVisualEffectsView:

var blurEffectView = UIVisualEffectView()
blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
Run Code Online (Sandbox Code Playgroud)

我在a调用的函数中使用普通动画UIButton来淡入它,同样用于淡出,但是.alpha = 0&hidden = true:

blurEffectView.hidden = false
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut) {
    self.blurEffectView.alpha = 1
}
Run Code Online (Sandbox Code Playgroud)

现在,在两个方向上褪色的工作,但衰落时,它给我一个错误:

<UIVisualEffectView 0x7fdf5bcb6e80>被要求动画其不透明度.这将导致效果出现断裂,直到不透明度返回到1.

如何成功地淡入淡出UIVisualEffectView而不会破坏它并且有一个渐弱的过渡?

注意

  • 我试图把它UIVisualEffectView变成一个UIView并且淡化那个,没有成功

jrt*_*ton 182

我认为这是iOS9中的新功能,但您现在可以设置UIVisualEffectView动画块内部的效果:

let overlay = UIVisualEffectView()
// Put it somewhere, give it a frame...
UIView.animate(withDuration: 0.5) {
    overlay.effect = UIBlurEffect(style: .light)
}
Run Code Online (Sandbox Code Playgroud)

将其设置nil为删除.

非常重要 - 在模拟器上测试时,请确保将模拟器的图形质量覆盖设置为高质量,以使其正常工作.

  • 您还可以将效果设置为nil以获得相当"模糊" (10认同)

and*_*der 18

苹果的文档(目前)指出...

使用UIVisualEffectView类时,请避免使用小于1的alpha值.

在视觉效果视图或其任何超视图上将alpha设置为小于1会导致许多效果看起来不正确或根本不显示.

我相信这里缺少一些重要的背景......

我建议目的是避免持久视图的小于1的alpha值.在我的拙见中,这不适用于视图的动画.

我的观点 - 我建议动画可以接受小于1的alpha值.

终端消息指出:

正在要求UIVisualEffectView为其不透明度设置动画.这将导致效果出现断裂,直到不透明度返回到1.

仔细阅读,效果似乎会被打破.我对此提出两点意见:

  • 明显的突破只对持久的观点 - 不改变;
  • UIVisualEffectAlpha值小于1 的持久/不变视图将不会按Apple的预期/设计呈现; 和
  • 终端中的消息不是错误,只是一个警告.

为了扩展@jrturton上面的答案,帮助我解决了我的问题,我补充说......

要淡出UIVisualEffect使用以下(Objective-C)代码:

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

我成功使用了两种方法:将effect属性nil设置为并将alpha属性设置为0.

注意,设置effectnil创建一个"好闪"(为了更好地说明想要的)在动画结束后,在设置alpha0创建一个平滑的过渡.

(让我知道任何语法错误......我用obj-c写.)


Gun*_*han 13

这是我最终使用Swift 3在iOS10和早期版本上运行的解决方案

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
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

您还可以查看此要点以查找示例用法.


ber*_*ium 8

只是一个解决方法 - 放入UIVisualEffectView容器视图并更改alpha该容器的属性.在iOS 9上,这种方法对我来说非常有效.似乎它不再适用于iOS 10.

  • 这在iOS 10中不再有效:​​( (10认同)
  • @damirstuhec如果您的项目仅限iOS 10,则可以使用新的UIViewPropertyAnimator类来设置UIBlurView强度的动画.如果您需要支持旧版本,可以使用上面的代码并使用#available关键字为运行10的设备使用UIViewPropertyAnimator.希望这会有所帮助! (2认同)

Dav*_*ton 5

除了控制台中的警告之外,您可以更改视觉效果视图的Alpha,而不会出现任何问题。视图可能只是部分透明,而不是模糊。但这通常不是问题,如果您只是在动画过程中更改Alpha。

您的应用不会因此崩溃或被拒绝。在真实设备(或八个)上进行测试。如果您对它的外观和性能感到满意,那就很好。Apple只是警告您,它的外观或效果可能不如alpha值为1的视觉效果视图。


Dav*_*d H 5

您可以拍摄静态基础视图的快照,并在不触及模糊视图的不透明度的情况下淡入淡出.假设一个模糊的ivar:

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()
    } )
}
Run Code Online (Sandbox Code Playgroud)