Как исчезать UIVisualEffectView и / или UIBlurEffect В и из?


Я хочу, чтобы исчезать UIVisualEffectsView с UIBlurEffect В и из:

var blurEffectView = UIVisualEffectView()
blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))

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

blurEffectView.hidden = false
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut) {
    self.blurEffectView.alpha = 1
}

теперь, затухание в обоих направлениях работает, но это дает мне ошибку при затухании из:

<UIVisualEffectView 0x7fdf5bcb6e80> просят анимировать его непрозрачность. Это вызовет эффект для до непрозрачности возвращается к 1.

вопрос

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

Примечание

  • я пытался поставить UIVisualEffectView на UIView и исчезают, что один, без успеха
15 80

15 ответов:

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

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

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

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

The документация Apple (в настоящее время) государств...

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

и

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

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

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

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

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

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

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

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

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

чтобы исчезнуть UIVisualEffect используйте следующий код (Objective-C):

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.)

вот решение, которое я закончил, которое работает как на 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
            }
        }
    }

}

вы можете проверьте эту суть найти пример использования.

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

вы можете сделать снимок статического базового вида и затемнить его, не касаясь непрозрачности размытого вида. Предполагая, что Ивар 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()
    } )
}

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

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

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

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

Если вы хотите исчезнуть в вас 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 вы можете использовать Альфа-компонент

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

Я закончил со следующим решением, используя отдельные анимации для 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 }

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

У меня просто была эта проблема, и я обошел ее, чтобы разместить UIVisualEffectsView в UIView и анимировать эту альфа-версию UIView.

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

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

_visualEffectView.contentView.alpha = 0;

изменить Альфа UIVisualEffectView, вы должны изменить на странице просмотр содержимого _visualEffectView.Если вы измените Альфа _visualEffectView, вы получите это

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

обычно я хочу только анимировать размытие, когда я представляю контроллер вида на экране и хочу размыть контроллер представления. Вот расширение, которое добавляет blur() и 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 (), чтобы убедиться, что это только один удален, когда Вы фото () и т. д., но я не нашел необходимости делать эти вещи до сих пор, так как это, как правило, "огонь и забыть" тип операции.

на основе ответа @cc я изменил его расширение, чтобы размыть вид

extension UIView {

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

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

улучшение @Tel4tel и @ cc ответ, вот расширение с параметрами и краткое объяснение.

extension UIView {

    // Perform a blur animation in the whole view
    // Effect tone can be .light, .dark, .regular...
    func blur(duration inSeconds: Double, effect tone: UIBlurEffectStyle) {
        let blurView = UIVisualEffectView(frame: self.bounds)
        self.addSubview(blurView)
        UIView.animate(withDuration: inSeconds) {
            blurView.effect = UIBlurEffect(style: tone)
        }
    }

    // Perform an unblur animation in the whole view
    func unblur(duration inSeconds: Double) {
        for childView in subviews {
            guard let effectView = childView as? UIVisualEffectView else { continue 
        }
            UIView.animate(withDuration: inSeconds, animations: {
                effectView.effect = nil
            }){
                didFinish in effectView.removeFromSuperview()
            }
        }
    }
}

затем вы можете использовать его как: view.blur(duration: 5.0, effect: .light) или view.unblur(duration: 3.0)

Не забудьте не использовать его в viewDidLoad() как он будет переопределять анимацию. Кроме того, при работе на симуляторе, поверните графику на более высокий уровень, чтобы иметь возможность видеть анимацию (Debug > Graphics Quality Override > High Quality).