Меньше размытия с помощью «Визуального эффекта с размытием»?

Название в значительной степени просит все это …

Я играю с Visual Effect View with Blur iOS8 Visual Effect View with Blur . Это над UIImageView который показывает пользовательскую фотографию. Представление, размещенное в самом содержимом contentView, является моим собственным пользовательским представлением, показывает вид графика / календаря. Большая часть графика календаря прозрачна. Размытие, которое оно применяет к фотографии за ней, действительно тяжело. Я бы хотел пропустить больше деталей. Но Apple только, кажется, дает три законченных значения:

 typedef enum { UIBlurEffectStyleExtraLight, UIBlurEffectStyleLight, UIBlurEffectStyleDark } UIBlurEffectStyle; 

Я поддерживал различные цвета альфа и фона UIVisualEffectView (хотя документация предупреждает об этом), но это не делает ничего, кроме ухудшения.

Причина, по которой вы получаете сильное размытие, заключается в том, что стиль эффекта размытия влияет на уровень яркости изображения, а не на количество размытости.

введите описание изображения здесь

К сожалению, хотя Apple явно имеет возможность контролировать количество размытия, применяемого программно, – попробуйте медленно перемещаться на панели запуска, чтобы посмотреть переход на размытие Spotlight – я не вижу, чтобы какой-либо публичный API передавал значение размытия UIBlurEffect .

В этом сообщении утверждается, что настройка альфа-фона фона приведет к увеличению размытости. Это стоит попробовать, но я не вижу, где это задокументировано: как угасать UIVisualEffectView и / или UIBlurEffect?

Жаль, что Apple не предоставила никаких вариантов эффекта размытия. Но это обходное решение сработало для меня – оживление эффекта размытия и приостановка его до завершения.

 func blurEffectView(enable enable: Bool) { let enabled = self.blurView.effect != nil guard enable != enabled else { return } switch enable { case true: let blurEffect = UIBlurEffect(style: .ExtraLight) UIView.animateWithDuration(1.5) { self.blurView.effect = blurEffect } self.blurView.pauseAnimation(delay: 0.3) case false: self.blurView.resumeAnimation() UIView.animateWithDuration(0.1) { self.blurView.effect = nil } } } 

и расширения UIView для приостановки (с задержкой) и возобновления анимации вида

 extension UIView { public func pauseAnimation(delay delay: Double) { let time = delay + CFAbsoluteTimeGetCurrent() let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, time, 0, 0, 0, { timer in let layer = self.layer let pausedTime = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) layer.speed = 0.0 layer.timeOffset = pausedTime }) CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes) } public func resumeAnimation() { let pausedTime = layer.timeOffset layer.speed = 1.0 layer.timeOffset = 0.0 layer.beginTime = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) - pausedTime } } 

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

Я UIVisualEffectView в UIView прежде чем добавлять к моему представлению.

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

 func addBlurArea(area: CGRect, style: UIBlurEffectStyle) { let effect = UIBlurEffect(style: style) let blurView = UIVisualEffectView(effect: effect) let container = UIView(frame: area) blurView.frame = CGRect(x: 0, y: 0, width: area.width, height: area.height) container.addSubview(blurView) container.alpha = 0.8 self.view.insertSubview(container, atIndex: 1) } 

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

 addBlurArea(self.view.frame, style: UIBlurEffectStyle.Dark) 

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

Добавьте BlurEffectView в представление с альфа-представлением вида <1

 func addBlurEffectView() -> Void { if !UIAccessibilityIsReduceTransparencyEnabled() { let viewContainer = UIView() viewContainer.frame = self.view.bounds viewContainer.alpha = 0.5 let blurEffect = UIBlurEffect(style: .dark) let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.layer.zPosition = -0.5; blurEffectView.frame = self.view.bounds; blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] viewContainer.addSubview(blurEffectView) self.view.addSubview(viewContainer) self.view.sendSubview(toBack: viewContainer) } } 

Да, ты можешь.

Вот пример UIImageView с эффектом размытия на нем. Не забудьте добавить изображение в UIImageView.

Отрегулируйте размер размытия с помощью blurEffectView.alpha = 0.8 (от 0 до 1)

 import UIKit class BlurEffectImageView: UIImageView { override func awakeFromNib() { addBlurEffect() super.awakeFromNib() } private func addBlurEffect(){ let blurEffect = UIBlurEffect(style: .light) let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.alpha = 0.8 blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] blurEffectView.translatesAutoresizingMaskIntoConstraints = false addSubview(blurEffectView) NSLayoutConstraint(item: blurEffectView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0).isActive = true NSLayoutConstraint(item: blurEffectView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0).isActive = true NSLayoutConstraint(item: blurEffectView, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 1.0, constant: 0).isActive = true NSLayoutConstraint(item: blurEffectView, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1.0, constant: 0).isActive = true } 

}

Этот ответ основан на превосходном более раннем ответе Митья Семиола . Я преобразовал его в swift 3, добавил объяснение тому, что происходит в коментах, сделал его расширением UIViewController, чтобы любой VC мог его вызвать по желанию, добавил неровное представление, чтобы показать выборочное приложение, и добавил блок завершения, чтобы контроллер вызова может делать все, что захочет, по завершении размытия.

  import UIKit //This extension implements a blur to the entire screen, puts up a HUD and then waits and dismisses the view. extension UIViewController { func blurAndShowHUD(duration: Double, message: String, completion: @escaping () -> Void) { //with completion block //1. Create the blur effect & the view it will occupy let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light) let blurEffectView = UIVisualEffectView()//(effect: blurEffect) blurEffectView.frame = self.view.bounds blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] //2. Add the effect view to the main view self.view.addSubview(blurEffectView) //3. Create the hud and add it to the main view let hud = HudView.getHUD(view: self.view, withMessage: message) self.view.addSubview(hud) //4. Begin applying the blur effect to the effect view UIView.animate(withDuration: 0.01, animations: { blurEffectView.effect = blurEffect }) //5. Halt the blur effects application to achieve the desired blur radius self.view.pauseAnimationsInThisView(delay: 0.004) //6. Remove the view (& the HUD) after the completion of the duration DispatchQueue.main.asyncAfter(deadline: .now() + duration) { blurEffectView.removeFromSuperview() hud.removeFromSuperview() self.view.resumeAnimationsInThisView() completion() } } } extension UIView { public func pauseAnimationsInThisView(delay: Double) { let time = delay + CFAbsoluteTimeGetCurrent() let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, time, 0, 0, 0, { timer in let layer = self.layer let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil) layer.speed = 0.0 layer.timeOffset = pausedTime }) CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes) } public func resumeAnimationsInThisView() { let pausedTime = layer.timeOffset layer.speed = 1.0 layer.timeOffset = 0.0 layer.beginTime = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime } } 

Я подтвердил, что он работает как с iOS 10.3.1, так и с iOS 11

Interesting Posts
Давайте будем гением компьютера.