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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29307827/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:23:42  来源:igfitidea点击:

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

iosswiftfadeuiblureffectuivisualeffectview

提问by LinusGeffarth

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

我想淡入淡出带有 UIBlurEffect 的 UIVisualEffectsView:

var blurEffectView = UIVisualEffectView()
blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))

I use a normal animation within a function called by a UIButtonto fade it in, same for fading out but .alpha = 0& hidden = true:

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

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

Now, fading in both directions does work but it gives me an error when fading out:

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

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

<UIVisualEffectView 0x7fdf5bcb6e80>被要求为其不透明度设置动画。这将导致效果出现损坏,直到不透明度恢复为 1。

Question

How do I successfully fade the UIVisualEffectViewin and out without breakingit and having a fading transition?

我如何成功地淡入淡出UIVisualEffectView而不会破坏它并有淡入淡出的过渡?

Note

笔记

  • I tried to put the UIVisualEffectViewinto a UIViewand fade that one, no success
  • 我试着把它放进UIVisualEffectViewUIView然后淡化那个,没有成功

回答by jrturton

I think this is new in iOS9, but you can now set the effect of a UIVisualEffectViewinside an animation block:

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

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

Set it to nilto remove.

将其设置nil为删除。

VERY IMPORTANT - When testing this on the simulator, make sure to set your simulator's Graphics Quality Override to High Quality in order for this to work.

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

回答by andrewbuilder

The Apple documentation(currently) states...

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

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

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

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.

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

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.

我建议这样做的目的是避免持久视图的 alpha 值小于 1。在我看来,这不适用于视图的动画。

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

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

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.

要求 UIVisualEffectView 为其不透明度设置动画。这将导致效果出现损坏,直到不透明度恢复为 1。

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

仔细阅读这个,效果似乎被打破了。我的观点是:

  • the apparent break only really matters for a view that is persistent - not changing;
  • a persistent / unchanging UIVisualEffectview 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.
  • 明显的中断仅对于持久的视图才真正重要 - 不会改变;
  • UIVisualEffectalpha 值小于 1的持久/不变视图将不会按 Apple 的预期/设计呈现;和
  • 终端中的消息不是错误,只是警告。

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

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

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

要淡出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()
} )

I successfully use both methods: setting the effectproperty to niland setting the alphaproperty to 0.

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

Note that setting the effectto nilcreates a "nice flash" (for want of a better description) at the end of the animation, while setting the alphato 0creates a smooth transition.

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

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

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

回答by Gunhan

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

这是我最终得到的解决方案,它适用于使用 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
            }
        }
    }

}

You can also check this gistto find an example usage.

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

回答by beryllium

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

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

回答by David H

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:

您可以拍摄静态底层视图的快照,并在不影响模糊视图的不透明度的情况下将其淡入淡出。假设一个模糊视图的 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()
    } )
}

回答by Dave Batton

You can change the alpha of the visual effects view without any problems, other than the warning in the console. The view may appear as simply partially transparent, rather than blurred. But this usually isn't a problem if you're just changing the alpha during animation.

除了控制台中的警告之外,您可以毫无问题地更改视觉效果视图的 alpha。视图可能看起来只是部分透明,而不是模糊。但是,如果您只是在动画期间更改 alpha,这通常不是问题。

Your app isn't going to crash or get rejected for this. Test it on a real device (or eight). If you're happy with how it looks and performs, it's fine. Apple's just warning you that it may not look or perform as well as a visual effects view with an alpha value of 1.

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

回答by kiril kiroski

If you want to fade in you UIVisualEffectView - for ios10 use UIViewPropertyAnimator

如果你想淡入你的 UIVisualEffectView - 对于 ios10 使用 UIViewPropertyAnimator

    UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:nil];
    blurEffectView.frame = self.view.frame;
    blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    UIView *blackUIView = [[UIView alloc]initWithFrame:self.view.frame];
    [bacgroundImageView addSubview:blackUIView];
    [blackUIView addSubview:blurEffectView];
    UIViewPropertyAnimator *animator  = [[UIViewPropertyAnimator alloc] initWithDuration:4.f curve:UIViewAnimationCurveLinear animations:^{
        [blurEffectView setEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
    }];

then you can set percent

然后你可以设置百分比

[animator setFractionComplete:percent];

for ios9 you can use alpha component

对于 ios9,您可以使用 alpha 组件

回答by Peter Lendvay

The alpha of the UIVisualEffectView always has to be 1. I think you can achieve the effect by setting the alpha of the background color.

UIVisualEffectView 的 alpha 必须始终为 1。我认为您可以通过设置背景颜色的 alpha 来实现效果。

Source : https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/index.html

来源:https: //developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/index.html

回答by demian

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

我最终得到了以下解决方案,为UIVisualEffectView和 内容使用单独的动画 。我使用该viewWithTag()方法来获取UIViewUIVisualEffectView.

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.

我更喜欢改变 alpha 的单个动画,但这避免了错误并且似乎也能正常工作。

回答by Kemal Can Kaynak

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.

我制作了一个 alpha 为 0 的 uiview 并添加了 blurview 作为它的子视图。所以我可以用动画隐藏/显示或圆角它。