Подтвердить что ты не робот

Как установить BlurRadius UIBlurEffectStyle.Light

Мне было интересно, как установить коэффициент радиуса/размытия 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)
}
4b9b3361

Ответ 1

Вы можете изменить альфа UIVisualEffectView, к которому вы добавляете эффект размытия.

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

Это не настоящее решение, так как оно фактически не изменяет радиус размытия, но я обнаружил, что он выполняет работу с очень небольшой работой.

Ответ 2

Хотя это взломать и, вероятно, он не будет принят в магазине приложений, это все еще возможно. Вы должны подклассифицировать 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

Здесь радиус размытия установлен на 50. Вы можете изменить 50 на любое значение, которое вам нужно.

Затем просто используйте MyBlurEffect класс вместо UIBlurEffect при создании эффекта для UIVisualEffectView.

Ответ 3

Недавно разработанная библиотека 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;

UPDATE:

Apple представила UIViewPropertyAnimator класс в iOS 10. Это то, что нам нужно, чтобы анимировать .effect свойство UIVisualEffectsView. Сообщество Hope сможет вернуть эту функциональность в предыдущую версию iOS.

Ответ 4

Изменение альфы не является идеальным решением. Это не влияет на интенсивность размытия. Вы можете настроить анимацию от nil до целевого эффекта размытия и вручную установить временное смещение, чтобы получить желаемую интенсивность размытия. К сожалению, iOS вернет смещение анимации, когда приложение вернется из фона.

К счастью, есть простое решение, которое работает на iOS> = 10. Вы можете использовать UIViewPropertyAnimator. Я не заметил никаких проблем с его использованием. Я сохраняю пользовательскую интенсивность размытия, когда приложение возвращается из фона. Вот как вы можете это реализовать:

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!

}

Я также создал суть: https://gist.github.com/darrarski/29a2a4515508e385c90b3ffe6f975df7

Ответ 5

Я боюсь, что такого апи нет. Согласно способу Apple делать вещи, новые функциональные возможности всегда были связаны с ограничениями, а возможности будут возникать постепенно. Возможно, это будет возможно на iOS 9 или, может быть, на 10...

Ответ 6

Это полностью выполнимо. Используйте CIFilter в модуле CoreImage чтобы настроить радиус размытия. На самом деле, вы даже можете добиться эффекта размытия с непрерывно меняющимся (иначе градиентным) радиусом размытия (fooobar.com/questions/6141514/...)

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)

Ответ 7

В настоящее время я не нашел никакого решения.
Кстати, вы можете добавить немного взлома, чтобы смазать маску менее "размытым", таким образом:

let blurView = .. // here create blur view as usually

if let blurSubviews = self.blurView?.subviews {
    for subview in blurSubviews {
        if let filterView = NSClassFromString("_UIVisualEffectFilterView") {
            if subview.isKindOfClass(filterView) {
                subview.hidden = true
            }
        }
    }
}

Ответ 8

Эта идея пришла мне в голову после того, как я попробовал вышеупомянутые решения, немного хакерский, но у меня все получилось. Поскольку мы не можем изменить радиус по умолчанию, который установлен как "50", мы можем просто увеличить его и уменьшить его.

previewView.snp.makeConstraints { (make) in
    make.centerX.centerY.equalTo(self.view)
    make.width.height.equalTo(self.view).multipliedBy(4)
}

previewBlur.snp.makeConstraints { (make) in
    make.edges.equalTo(previewView)
}

А потом,

previewView.transform = CGAffineTransform(scaleX: 0.25, y: 0.25)
previewBlur.transform = CGAffineTransform(scaleX: 0.25, y: 0.25)

Я получил радиус размытия 12,5. Надеюсь, это поможет :-)

Ответ 9

Это работает для меня.

Я помещаю UIVisualEffectView в UIView перед добавлением в мое представление.

Я делаю эту функцию более простой. Вы можете использовать эту функцию, чтобы размыть любую область в вашем представлении.

func addBlurArea(area: CGRect) {
    let effect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
    let blurView = UIVisualEffectView(effect: effect)
    blurView.frame = CGRect(x: 0, y: 0, width: area.width, height: area.height)

    let container = UIView(frame: area)
    container.alpha = 0.8
    container.addSubview(blurView)

    self.view.insertSubview(container, atIndex: 1)
}

Например, вы можете размыть все свое мнение, вызвав:

addBlurArea(self.view.frame)

Вы можете изменить Dark на желаемый стиль размытия и 0.8 на нужное значение альфа

Ответ 10

Если вы хотите выполнить то же поведение, что и поиск прожекторов iOS, вам просто нужно изменить альфа-значение UIVisualEffectView (проверено на симуляторе iOS9)