【问题标题】:How to use UIVisualEffectView to Blur Image?如何使用 UIVisualEffectView 模糊图像?
【发布时间】:2014-07-26 21:22:55
【问题描述】:

有人可以举一个将模糊应用于图像的小例子吗?我一直在尝试找出代码有一段时间了 :( 在 obj c 还是新的!

UIVisualEffectView 提供了对复杂的简单抽象 视觉效果。根据所需的效果,结果可能 影响视图后面的内容或添加到视图的内容 内容视图。

UIVisualEffectView 应用于现有视图以应用模糊或 现有视图的活力效果。添加后 UIVisualEffectView 到视图层次结构中,将任何子视图添加到 UIVisualEffectView 的内容视图。不要直接添加子视图 UIVisualEffectView 本身。

https://developer.apple.com/documentation/uikit/uivisualeffectview#//apple_ref/occ/instp/UIVisualEffectView/contentView

【问题讨论】:

  • 小心添加视图到UIVisualEffectViewcontentViewgithub.com/onmyway133/blog/issues/124
  • 另外,如果您将其添加到子视图并设置其框架,请不要忘记在 viewDidLayoutSubviews 中更新框架以确保旋转正常。

标签: ios objective-c uiview uikit uivisualeffectview


【解决方案1】:

这里是如何将 UIVibrancyEffect 和 UIBlurEffect 与 UIVisualEffectView 一起使用

目标-C:

// Blur effect
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
[self.view addSubview:blurEffectView];

// Vibrancy effect
UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
UIVisualEffectView *vibrancyEffectView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect];
[vibrancyEffectView setFrame:self.view.bounds];

// Label for vibrant text
UILabel *vibrantLabel = [[UILabel alloc] init];
[vibrantLabel setText:@"Vibrant"];
[vibrantLabel setFont:[UIFont systemFontOfSize:72.0f]];
[vibrantLabel sizeToFit];
[vibrantLabel setCenter: self.view.center];

// Add label to the vibrancy view
[[vibrancyEffectView contentView] addSubview:vibrantLabel];

// Add the vibrancy view to the blur view
[[blurEffectView contentView] addSubview:vibrancyEffectView];

斯威夫特:

// Blur Effect
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
view.addSubview(blurEffectView)

// Vibrancy Effect
let vibrancyEffect = UIVibrancyEffect(blurEffect: blurEffect)
let vibrancyEffectView = UIVisualEffectView(effect: vibrancyEffect)
vibrancyEffectView.frame = view.bounds

// Label for vibrant text
let vibrantLabel = UILabel()
vibrantLabel.text = "Vibrant"
vibrantLabel.font = UIFont.systemFont(ofSize: 72.0)
vibrantLabel.sizeToFit()
vibrantLabel.center = view.center

// Add label to the vibrancy view
vibrancyEffectView.contentView.addSubview(vibrantLabel)

// Add the vibrancy view to the blur view
blurEffectView.contentView.addSubview(vibrancyEffectView)

【讨论】:

  • 解决方法即使没有子类化也有效,只需定义extension UILabel { override func tintColorDidChange() { textColor = tintColor; super.tintColorDidChange() } }
  • Apple 似乎已经修复了这个错误。在 iOS 8 beta 2 中不再需要子类/扩展解决方法。
  • 谢谢。我已经测试并确认了错误修复并编辑了答案。
  • 我试图将其添加到我的视图中,但每次我呈现视图时,它都会一遍又一遍地模糊,直到我得到白色背景...我在关闭它后使用 removeFromSuperView 删除视图但我得到了相同的结果....有什么想法吗?
  • @GeorgeAsda 不打电话给removeFromSuperView,你叫[self.visualEffectView setHidden:NO]; 怎么样?分配和添加到视图上的操作比隐藏或显示要昂贵。
【解决方案2】:

只需将此模糊视图放在 imageView 上即可。下面是 Objective-C 中的一个例子:

UIVisualEffect *blurEffect;
blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];

UIVisualEffectView *visualEffectView;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];

visualEffectView.frame = imageView.bounds;
[imageView addSubview:visualEffectView];

和斯威夫特:

var visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))    

visualEffectView.frame = imageView.bounds

imageView.addSubview(visualEffectView)

【讨论】:

  • 非常感谢!我忘了设置框架:(谷歌上还没有任何视觉效果,所以这应该是第一个搜索词:)
  • 希望 API 不会改变!这就是讨论尚未发布的 Apple API 可能很棘手的原因之一。例如,一些 UIKit Dynamics API 在 beta 和 release 之间略有变化。没什么大不了的,但他们会破坏针对原始 API 编写的任何示例代码。
  • 是否有动画模糊输入/输出?
  • @B.S.您可以为视觉效果视图的 Alpha 设置动画。繁荣。
  • UIBlurEffect 很棒,但请注意它不适用于 iPad2 等旧设备 - 我花了几个小时试图弄清楚为什么它只是在我的屏幕上放置了一个半透明层而不是模糊 - 这就是全部因为我在旧设备上进行测试
【解决方案3】:

如果有人想要 Swift 中的答案:

var blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark) // Change .Dark into .Light if you'd like.

var blurView = UIVisualEffectView(effect: blurEffect)

blurView.frame = theImage.bounds // 'theImage' is an image. I think you can apply this to the view too!

更新:

截至目前,它在 IB 下可用,因此您无需为它编写任何代码 :)

【讨论】:

    【解决方案4】:
    -(void) addBlurEffectOverImageView:(UIImageView *) _imageView
    {
        UIVisualEffect *blurEffect;
        blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    
        UIVisualEffectView *visualEffectView;
        visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    
        visualEffectView.frame = _imageView.bounds;
        [_imageView addSubview:visualEffectView];
    }
    

    【讨论】:

    • 添加一些带有答案的文本,说明您的答案如何帮助 OP 修复已发布的问题
    【解决方案5】:

    我更喜欢通过 Storyboard 创建视觉效果 - 没有用于创建或维护 UI 元素的代码。它也为我提供了全面的景观支持。我做了一个小演示,将 UIVisualEffects 与 Blur 和 Vibrancy 结合使用。

    Demo on Github

    【讨论】:

      【解决方案6】:

      您还可以使用界面构建器为简单的情况轻松创建这些效果。由于视图的 z 值取决于它们在文档大纲中列出的顺序,因此您可以将 UIVisualEffectView 拖到要模糊的视图之前的文档大纲上。这会自动创建一个嵌套的UIView,它是给定UIVisualEffectViewcontentView 属性。在此视图中嵌套您希望显示在模糊之上的内容。

      您还可以轻松利用活力UIVisualEffect,它会在默认启用活力的文档大纲中自动创建另一个嵌套UIVisualEffectView。然后,您可以将标签或文本视图添加到嵌套的UIView(同样是UIVisualEffectViewcontentView 属性),以实现与“>滑动解锁”UI元素相同的效果。

      【讨论】:

      • 您能确认所显示的内容实际上是模糊的吗?我的图像(您在层次结构中称为“BackgroundPhoto”)只是在模糊样式下变暗:深色半透明视图。 (Xcode 6.01 发行版并使用 iOS 模拟器)
      • 你是什么意思'只是变暗'?那你不觉得它很模糊吗?
      • 好的,我过几个小时去看看。
      • 谢谢!您的 BackgroundPhoto 上有一个视图层次结构,它在屏幕截图中折叠...我只是使用了 UIImageView 并为其分配了一张照片(绿色背景下的浅色狗 - 白色腿和绿草之间的清晰定义是被视觉效果视图覆盖时和没有时一样清晰)。
      • 我已经看到将模糊类型更改为深色,标签变为白色......