Странное поведение UIVisualEffectView в многозадачности

У меня есть AccountsViewController, который имеет UIVisualEffectView с эффектом размытия в фоновом режиме (подзаголовок с индексом 0), так что он покрывает предыдущий контроллер размытием во время перехода. Но когда я затем переключаюсь на другое приложение и снова открываю меню многозадачности, чтобы вернуться к моему приложению, его размытый UIVisualEffectView кажется поврежденным (как показано на снимке экрана 1). Когда я снова делаю свое приложение активным, представление «восстанавливается» и снова выглядит нормально (как показано на втором снимке экрана).

поврежденный UIVisualEffectView получается нормально через несколько миллисекунд после выбора приложения

Некоторый код из моего пользовательского класса перехода, где я добавляю представление размытия

// in the animateTransition.. method
guard let container = transitionContext.containerView() else {
            return
        }
let blurEffectView: UIVisualEffectView
        if container.viewWithTag(101) != nil {
            blurEffectView = container.viewWithTag(101)! as! UIVisualEffectView
        }
        else {
            blurEffectView = UIVisualEffectView(frame: container.frame)
            blurEffectView.translatesAutoresizingMaskIntoConstraints = false
            blurEffectView.tag = 101
            container.addSubview(blurEffectView)
        }

        if self.isPresenting {
            // We're presenting a view controller over another
            toViewController.view.transform = CGAffineTransformMakeScale(0.7, 0.7)
            container.addSubview(toViewController.view)
            container.sendSubviewToBack(blurEffectView)
            toViewController.view.alpha = 0

            UIView.animateWithDuration(self.transitionDuration(transitionContext), delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.8, options: [], animations: { () -> Void in
                fromViewController.view.transform = CGAffineTransformMakeScale(0.8, 0.8)
                toViewController.view.transform = CGAffineTransformMakeScale(1, 1)
                blurEffectView.effect = UIBlurEffect(style: .Dark)
                toViewController.view.alpha = 1
            }, completion: { (completed) -> Void in
                self.context?.completeTransition(completed)
            })
        }
        else {
            // We're dismissing a view controller
            UIView.animateWithDuration(self.transitionDuration(transitionContext), delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.8, options: [], animations: { () -> Void in
                fromViewController.view.transform = CGAffineTransformMakeScale(0.7, 0.7)
                toViewController.view.transform = CGAffineTransformMakeScale(1, 1)
                blurEffectView.effect = nil
                fromViewController.view.alpha = 0
            }, completion: { (completed) -> Void in
                fromViewController.view.removeFromSuperview()
                self.context?.completeTransition(completed)
            })
        }

person khabiroff    schedule 20.03.2016    source источник


Ответы (1)


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

  • представление fromViewController (с преобразованием масштаба 0,8; 0,8)
  • UIVisualEffectView с примененным к нему размытием в стиле .Dark
  • представление toViewController

Из-за размера представления fromViewController (который был меньше экрана из-за масштабного преобразования) черное представление UIWindow просвечивало. И, согласно моему исследованию, это приводит к тому, что UIVisualEffectView вызывает сбой, описанный в этом вопросе.

Решение состоит в том, чтобы добавить черный UIView с рамкой UIWindow и добавить его в конец иерархии представлений контейнера:

let blackView = UIView(frame: container.frame)
blackView.backgroundColor = UIColor.blackColor()
container.insertSubview(blackView, atIndex: 0)

А то этот глюк вроде больше не появляется.

person khabiroff    schedule 01.04.2016