如何设置UIBlurEffectStyle.Light的BlurRadius

fab*_*ian 52 swift

我想知道如何设置iOS新UIBlurEffectStyle.Light的半径/模糊因子?我在文档中找不到任何内容.但我希望它看起来类似于经典的"UIImage + ImageEffects.h"模糊效果.

谢谢,

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    let blur:UIBlurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
    let effectView:UIVisualEffectView = UIVisualEffectView (effect: blur)
    effectView.frame = frame
    addSubview(effectView)
}
Run Code Online (Sandbox Code Playgroud)

Dar*_*ski 28

改变alpha不是一个完美的解决方案.它不会影响模糊强度.您可以设置动画nil到目标模糊效果并手动设置时间偏移以获得所需的模糊强度.不幸的是,当app从后台返回时,iOS会重置动画偏移.

值得庆幸的是,有一个简单的解决方案适用于iOS> = 10.您可以使用UIViewPropertyAnimator.我没有注意到使用它的任何问题.当app从后台返回时,我保持自定义模糊强度.以下是如何实现它:

class CustomIntensityVisualEffectView: UIVisualEffectView {

    /// Create visual effect view with given effect and its intensity
    ///
    /// - Parameters:
    ///   - effect: visual effect, eg UIBlurEffect(style: .dark)
    ///   - intensity: custom intensity from 0.0 (no effect) to 1.0 (full effect) using linear scale
    init(effect: UIVisualEffect, intensity: CGFloat) {
        super.init(effect: nil)
        animator = UIViewPropertyAnimator(duration: 1, curve: .linear) { [unowned self] in self.effect = effect }
        animator.fractionComplete = intensity
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

    // MARK: Private
    private var animator: UIViewPropertyAnimator!

}
Run Code Online (Sandbox Code Playgroud)

我还创建了一个要点:https://gist.github.com/darrarski/29a2a4515508e385c90b3ffe6f975df7

  • 利用完整的分数是一个非常聪明的解决方案。据我所知,这是使用 UIBlurEffect 进行适当的逐渐模糊的唯一方法。更改模糊视图的 Alpha 会破坏效果,不应使用。 (2认同)
  • 添加“animator.pausesOnCompletion = true”以获得一致的结果。否则动画可能会被重置。 (2认同)

小智 26

您可以更改添加模糊效果的UIVisualEffectView的Alpha.

let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.alpha = 0.5
blurEffectView.frame = self.view.bounds
self.view.addSubview(blurEffectView)
Run Code Online (Sandbox Code Playgroud)

这不是一个真正的解决方案,因为它实际上并没有改变模糊的半径,但我发现它可以用很少的工作完成工作.

  • 使用UIVisualEffectView类时,请避免小于1的Alpha值.创建部分透明的视图会导致系统在屏幕外渲染过程中组合视图和所有关联的子视图.UIVisualEffectView对象需要组合为它们分层的内容的一部分,以便看起来正确.在视觉效果视图或其任何超视图上将alpha设置为小于1会导致许多效果看起来不正确或根本不显示.https://developer.apple.com/library/tvos/documentation/UIKit/Reference/UIVisualEffectView/index.html (20认同)

Eug*_*nyk 20

虽然它是一个黑客,可能它不会被应用程序商店接受,它仍然是可能的.你必须UIBlurEffect像这样继承子类:

#import <objc/runtime.h>

@interface UIBlurEffect (Protected)
@property (nonatomic, readonly) id effectSettings;
@end

@interface MyBlurEffect : UIBlurEffect
@end

@implementation MyBlurEffect

+ (instancetype)effectWithStyle:(UIBlurEffectStyle)style
{
    id result = [super effectWithStyle:style];
    object_setClass(result, self);

    return result;
}

- (id)effectSettings
{
    id settings = [super effectSettings];
    [settings setValue:@50 forKey:@"blurRadius"];
    return settings;
}

- (id)copyWithZone:(NSZone*)zone
{
    id result = [super copyWithZone:zone];
    object_setClass(result, [self class]);
    return result;
}

@end
Run Code Online (Sandbox Code Playgroud)

此处模糊半径设置为50.您可以将50更改为您需要的任何值.

然后只使用MyBlurEffect类而不是UIBlurEffect在创建效果时使用UIVisualEffectView.


k06*_*06a 18

最近开发的Bluuur库可动态改变模糊半径而UIVisualEffectsView无需使用任何私有API:https://github.com/ML-Works/Bluuur

它使用暂停的设置动画effect来实现模糊的半径变化.基于这个要点的解决方案:https://gist.github.com/n00neimp0rtant/27829d87118d984232a4

主要思想是:

// Freeze animation
blurView.layer.speed = 0;

blurView.effect = nil;
[UIView animateWithDuration:1.0 animations:^{
    blurView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
}];

// Set animation progress from 0 to 1
blurView.layer.timeOffset = 0.5;
Run Code Online (Sandbox Code Playgroud)

更新:

Apple 在iOS 10中引入了UIViewPropertyAnimator类.这就是我们需要准确动画的.effect属性UIVisualEffectsView.Hope社区将能够将此功能反向移植到以前的iOS版本.

  • 这应该是公认的答案.目前接受的是直接针对[Apple的指南](https://developer.apple.com/reference/uikit/uivisualeffectview). (2认同)
  • 自 2016 年 12 月和提交 https://github.com/ML-Works/Bluuur/commit/bf531b081bb10d2c76b9fe44411953ee54074b66 以来,Bluuur 项目**确实**使用私有 API 来更改 blurRadius!看到这个问题:https://github.com/ML-Works/Bluuur/issues/17 (2认同)

JGu*_*Guo 6

这是完全可行的。CIFilter在模块中使用CoreImage来自定义模糊半径。事实上,您甚至可以通过连续变化(又名渐变)模糊半径来实现模糊效果(/sf/answers/3612233761/

import CoreImage

let ciContext = CIContext(options: nil)

guard let inputImage = CIImage(image: yourUIImage), 
    let mask = CIFilter(name: "CIGaussianBlur") else { return }
mask.setValue(inputImage, forKey: kCIInputImageKey)
mask.setValue(10, forKey: kCIInputRadiusKey) // Set your blur radius here

guard let output = mask.outputImage,
    let cgImage = ciContext.createCGImage(output, from: inputImage.extent) else { return }
outUIImage = UIImage(cgImage: cgImage)
Run Code Online (Sandbox Code Playgroud)

  • 以免我们忘记 CoreImage (3认同)

小智 4

恐怕目前还没有这样的api。按照苹果的行事方式,新的功能总是有限制的,而功能则是逐渐显现出来的。也许这在 iOS 9 或 10 上是可能的......

  • 2016 年的你好。iOS 9.2 已经发布了,但仍然没有blurRadius。 (19认同)
  • iOS10?还是没有 ́\_(ツ)_/̅ (6认同)
  • iOS 11?奥兹===3 (3认同)
  • iOS12?还是没有 ́\\_(ツ)_/́ (3认同)
  • iOS13?还是没有 ́\\_(ツ)_/́ (3认同)
  • iOS 13 - [blur(radius:opaque:)](https://developer.apple.com/documentation/swiftui/view/blur(radius:opaque:)),适用于 SwiftUI (3认同)
  • iOS 14?还是不行,明天 iOS 15 发布可能还是不行.. (3认同)
  • iOS15...还是没有 ́\_(ツ)_/̊ (3认同)
  • iOS16...还是没有 ́\\_(ツ)_/̊ (2认同)