2015-03-27 10 views
69

Я хочу исчезать UIVisualEffectsView с UIBlurEffect в и:Как вывести и отобразить UIVisualEffectView и/или UIBlurEffect?

var blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark) 
var blurEffectView = UIVisualEffectView() 
blurEffectView = UIVisualEffectView(effect: blurEffect) 

Я использую обычную анимацию в функции, вызываемой с помощью UIButton угасать его, то же самым для выведения но .alpha = 0 & hidden = true:

UIView.animateWithDuration(1, delay:0, options: .CurveEaseOut, animations: { 
    self.blurEffectView.alpha = 1 
}, completion: { finished in 
    self.blurEffectView.hidden = false 
}) 

Теперь замирания в обоих направлениях делает работу, но он дает мне ошибку, когда угасание из: <UIVisualEffectView 0x7fdf5bcb6e80> is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1.

Вопрос

Как успешно исчезать UIVisualEffectsView в и без нарушения это и имеет затухающий переход?

Примечание

  • Я пытался поставить UIVisualEffectView в UIView и исчезать, что один, ни успеха
+0

Вы можете избежать ошибки: 1. НЕ присваивать начальный стиль blurEffect. т. е. var blurEffectView = UIVisualEffectView(), а затем 2. назначить blurEffect блоку анимации blurEffectView INSIDE. 3. Анимирование «назначение blurEffect для blurEffectView» выполняется вместо настроек blurEffectView.alpha. ** Ошибка появится, даже если вы назначили начальное значение, ноль, а затем добавите его обратно. Таким образом, ключом к предотвращению ошибки является не присвоение эффекта blurEffectView до блока анимации. – ObjectiveTC

+0

Также необходимо отметить, что blurEffectView должен иметь альфа = 1.0, чтобы избежать ошибки. Повреждение с альфой каким-либо образом приведет к ошибке. Например, перед блоком анимации вы устанавливаете blurEffectView.alpha = 0,7, то в анимационном блоке вы назначаете blurEffectView.effect = blurEffect, возникает ошибка. – ObjectiveTC

ответ

154

Я думаю, что это новое в iOS9, но теперь вы можете установить эффект UIVisualEffectView внутри анимационного блока:

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

Установите его в nil удалить.

+1

Работает отлично. Благодарю. – Baza207

+0

Именно то, что я хочу. Большое спасибо! –

+0

Отлично! Как вы сказали, не работает для iOS 8:/ – LinusGeffarth

2

альфа в UIVisualEffectView всегда должен быть 1. Я думаю, что вы можете добиться эффекта, установив альфа цвета фона.

Источник: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/index.html

+0

Питер, не могли бы вы объяснить, как установить альфа цвета фона? –

+0

@borisy использует метод colorWithAlphaComponent: 'в экземплярах' UIColor'. Не знаете, как добиться такого же эффекта при настройке цвета фона. – nemesis

+0

Изменяя фон, компонент альфа не работает должным образом –

4

Вы можете изменить альфа визуальных эффектов просматривать без каких-либо проблем, кроме предупреждения в консоли. Представление может выглядеть просто частично прозрачным, а не размытым. Но это обычно не проблема, если вы просто изменяете альфу во время анимации.

Ваше приложение не будет разбиваться или отклонено для этого. Протестируйте его на реальном устройстве (или восемь). Если вы довольны тем, как это выглядит и работает, все в порядке. Apple просто предупреждает вас о том, что он может выглядеть и не выглядеть так, как визуальный эффект с альфа-значением 1.

8

Просто обходное решение - положите UIVisualEffectView в вид контейнера и измените свойство alpha для этого контейнера. Этот подход отлично работает для меня на iOS 9. Кажется, он больше не работает в iOS 10.

+0

Прохладный. Спасибо, попробуем это :) – LinusGeffarth

+0

Пробовал это в навигационной панели, и это не сработало. – Jeremiah

+1

Можете ли вы предоставить пример кода. Кажется, это не работает. – cnotethegr8

5

Вы можете сделать снимок статического основного вида и вывести его из него, не касаясь непрозрачности размытия. Если предположить, что Ивар из blurView:

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() 
    }) 
} 
+0

Хорошая идея, но это не сработает n-static (перемещение/анимация) контента под размытием. – LinusGeffarth

+0

@LinusG. Ну, Apple говорит, что не следует играть с альфа-размытием. Вы можете использовать CADisplayLink для захвата снимков экрана вашего базового вида, а затем визуализировать их в режиме просмотра изображений (возможно, один из них - реальный легкий) - и показывать их в верхнем виде, изменяя его непрозрачность до 0. Возможно, но много Работа. –

+1

Это был единственный способ (до сих пор) я смог добиться того, чего я хотел в iOS 10 - исчезнуть в модальном режиме по всему экрану, с очень темным эффектом размытия. Благодаря! – Graham

1

В итоге я получил следующее решение, используя отдельные анимации для UIVisualEffectView и содержимого. Я использовал метод viewWithTag(), чтобы получить ссылку на UIView внутри UIVisualEffectView.

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 } 

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

1

Я делаю uiview, альфа которого равна 0 и добавляет blurview в качестве подзадачи этого. Поэтому я могу скрыть/показать или закруглить углы с помощью анимации.

14

Apple documentation (в настоящее время) заявляет ...

При использовании класса UIVisualEffectView, избежать альфа-значения, которые меньше 1.

и

Установка альфа до менее 1 в представлении визуального эффекта или любом из его наблюдений заставляет многие эффекты выглядеть некорректными или вообще не отображаться.

Я считаю, что какой-то важный контекст здесь отсутствует ...

Я хотел бы предложить, что намерение состоит в том, чтобы избежать альфа-значения, которые меньше 1 для постоянного вида. По моему скромному мнению, это не относится к анимации представления.

Мое мнение - я бы предположил, что альфа-значения менее 1 приемлемы для анимации.

Терминал сообщение гласит:

UIVisualEffectView спрашивается анимировать его непрозрачность. Это вызовет эффект появляться сломано, пока помутнение не возвращается 1.

Читая это тщательно, то эффект будет появляется быть нарушены. Я делаю две точки в этом отношении:

  • Очевидный разрыв действительно имеет значение для постоянного зрения - не меняется;
  • постоянный/неизменный UIVisualEffect вид с альфа-значением менее 1 не будет отображаться как предназначено/спроектировано Apple; и
  • сообщение в терминале не является ошибкой, просто предупреждение.

Чтобы продлить ответ @ jrturton в выше, которые помогли мне решить мою проблему, я хотел бы добавить ...

Чтобы приглушить UIVisualEffect использовать следующее:

UIView.animateWithDuration(1.0, animations: { 
// EITHER... 
    self.blurEffectView.effect = UIBlurEffect(nil) 
// OR... 
    self.blurEffectView.alpha = 0 
}, completion: { (finished: Bool) -> Void in 
    self.blurEffectView.removeFromSuperview() 
}) 

Я успешно использовать оба методы: установка effect собственности на nil и установка alpha собственности на 0.

Обратите внимание, что установка effect к nil создает «хорошую вспышку» (за неимением лучшего описания) в конце анимации, при установке alpha в 0 создает плавный переход.

(Дайте мне знать, какие синтаксические ошибки ... Я пишу в Obj-C.)

+0

Спасибо за ваш вклад. Я понимаю ваше мнение; ошибка разрешена для меня уже с тобой, о чем вы упоминали :) – LinusGeffarth

0
_visualEffectView.contentView.alpha = 0; 

Чтобы изменить альфа UIVisualEffectView, вы должны изменить contentView из _visualEffectView.If изменить альфа _visualEffectView , вы получите этот

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

проверено не работает в Xcode 8/iOS 10. – aBikis

1

Если вы хотите, чтобы исчезнуть в вас 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]]; 
    }]; 

, то вы можете установить процент

[animator setFractionComplete:percent]; 

для ios9 вы можете использовать альфа-компонент

+0

Вопрос специально помечен как «быстрый», а не «цель-c»: просьба указать ответ в Swift. Благодаря! – Moritz

6

Вот решение, что я в конечном итоге, который работает как на iOS10 и более ранних версий с помощью Swift 3

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 
      } 
     } 
    } 

} 

Вы также можете использовать check this gist, чтобы найти пример использования.

+0

Использование 'UIViewPropertyAnimator' - единственное, что работает в iOS 11. Спасибо за это! – LinusGeffarth

0

Обычно я хочу только размыть смайлик, когда я представляю контроллер представления по экрану и хочу размыть презентационный контроллер представления. Вот расширение, которое добавляет размытие() и unblur() в контроллере представления для того, чтобы облегчить этот процесс:

extension UIViewController { 

    func blur() { 
     // Blur out the current view 
     let blurView = UIVisualEffectView(frame: self.view.frame) 
     self.view.addSubview(blurView) 
     UIView.animate(withDuration:0.25) { 
      blurView.effect = UIBlurEffect(style: .light) 
     } 
    } 

    func unblur() { 
     for childView in view.subviews { 
      guard let effectView = childView as? UIVisualEffectView else { continue } 
      UIView.animate(withDuration: 0.25, animations: { 
       effectView.effect = nil 
      }) { 
       didFinish in 
       effectView.removeFromSuperview() 
      } 
     } 
    } 
} 

Вы, конечно, можете сделать это более надежным, позволяя пользователю выбрать тип эффекта, изменить продолжительность, вызывать что-то, когда анимация завершена, пометить добавленный визуальный эффект в blur(), чтобы убедиться, что он удаляется только при разрыве() и т. д., но я не нашел необходимости делать это до сих пор, поскольку это, как правило, операция «огонь и забухание».

+0

«огонь и забыть» настолько относительный! ха – LinusGeffarth

1

У меня просто была эта проблема, и так, как я обходился, это было размещение UIVisualEffectsView в UIView и анимация этой альфа-версии UIView.

Это сработало хорошо, за исключением того, что, как только альфа изменилась ниже 1.0, она превратилась в сплошной белый цвет и выглядела очень резкой. Чтобы обойти это, вы должны установить свойство слоя UIView containerView.layer.allowsGroupOpacity = false, и это предотвратит его прошивку белым цветом.

Теперь вы можете анимировать в/fade out UIView, содержащий вид визуальных эффектов, и любые другие подпункты, используя его альфа-свойство, и не должны беспокоиться о каких-либо графических сбоях или регистрировать предупреждающее сообщение.