Черный или серый фон под UIViewController с эффектом размытия

У меня в приложении несколько вкладок (UITabBarController), и в одной из них я могу показать модальный UIViewController с эффектом размытия (поверх текущего контроллера из вкладки).

    let bVC = BlurViewController()
    bVC.modalPresentationStyle = .overCurrentContext
    self.present(bVC, animated: true, completion: nil)

Размытый контроллер — это просто UIViewController с этим кодом в viewDidLoad:

    let blurEffect = UIBlurEffect(style: .extraLight)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView.frame = self.view.frame

    self.view.insertSubview(blurEffectView, at: 0)

Первая проблема у меня здесь, другие вкладки все еще доступны. Пользователь может нажимать на них, не закрывая мой размытый контроллер.

Элементы вкладок по-прежнему доступны

Это не настоящая проблема, но когда этот пользователь возвращается, мой размытый контроллер просмотра имеет серый фон. Оно и понятно, все области за ним не перерисовывались, но это беда.

Серый фон

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

Я знаю, что могу бороться с двумя последними проблемами с помощью этого:

  1. убрать размытый контроллер в viewDidDisappear.

  2. помните «размытое состояние» в его родительском контроллере.

  3. если пользователь вернулся, снова показать размытый контроллер.

Но, может быть, есть более элегантный и простой подход?


person lithium    schedule 20.10.2016    source источник


Ответы (1)


Попробуйте этот код: Протестировано в Swift 3.

Первый венчурный фонд

   import UIKit

   class ViewController: UIViewController {

   @IBOutlet weak var imageView: UIImageView!

   override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    title = "First VC"

    //To set Background image 
    let backgroundImage = UIImage(named: "Set any image for 1st VC")
    view.backgroundColor = UIColor(patternImage: backgroundImage!)
    imageView.contentMode = .scaleToFill

    // To set BlurView
    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
    let blurView = UIVisualEffectView(effect: blurEffect)
    blurView.frame = view.frame
    imageView.addSubview(blurView)

}
  // First VC barButton 

  Note: Connect firstVc to SecondVc using segue and set identifier name to **one**

  @IBAction func toSecondVC(_ sender: AnyObject) {

    performSegue(withIdentifier: "one", sender: self)

}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if (segue.identifier == "one") {

        navigationController?.navigationBar.isHidden = false

        navigationController?.toolbar.isHidden = false

    }
   }
  }

Второй VC

 import UIKit
 class viewTwo: UIViewController {

@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    title = "Second VC"
    let backgroundImage = UIImage(named: "Set any image for 2nd VC")
    view.backgroundColor = UIColor(patternImage: backgroundImage!)
    imageView.contentMode = .scaleToFill

    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
    let blurView = UIVisualEffectView(effect: blurEffect)
    blurView.frame = view.frame
    imageView.addSubview(blurView)

}

override func viewWillAppear(_ animated: Bool) {
    self.navigationItem.setHidesBackButton(true, animated:true)
}

@IBAction func backToMainVC(_ sender: AnyObject) {

//    dismiss(animated: true, completion: nil)
    navigationController?.popViewController(animated: true)
}  

}

Вывод из кода:

Примечание. Размытие выглядит несовершенным из-за ScreenCast, а не из-за кода...

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

person Joe    schedule 20.10.2016
comment
спасибо, но я не уверен, что это имеет отношение к моей проблеме. в вашем примере у вас есть два отдельных контроллера просмотра с размытым фоном (и это работает, очевидно, потому что любой из них будет перерисован). в моем случае у меня есть один контроллер просмотра поверх другого (и этот контроллер просмотра за размытым не перерисовывается). - person lithium; 20.10.2016
comment
Теперь я понял. Вы должны упомянуть, что используете UITabBarController.not 2 viewController, перекрывающих друг друга. - person Joe; 20.10.2016
comment
нет, это код из примера проекта. я не передаю никаких данных между этими контроллерами (кроме bVC.modalPresentationStyle = .overCurrentContext, как вы можете видеть в моих фрагментах кода). - person lithium; 20.10.2016
comment
Ясно. Теперь твоя проблема становится еще проще... знаешь, ты все еще можешь использовать мой ответ. Применяется та же логика... - person Joe; 20.10.2016
comment
нет, у моего item1 есть какая-то кнопка. когда эта кнопка нажата, будет показан uiviewcontroller (с размытым изображением внутри). - person lithium; 20.10.2016
comment
позвольте мне внести ясность. если вы используете tabBarController, это означает, что item1 всегда находится там и всегда презентабелен. Вы не можете выполнить переход. вы делаете неправильный подход или еще не упомянули. Можете ли вы обновить свой пост с помощью иерархии MainStoryBoard. чтобы я мог видеть, как связаны раскадровки. Мое время ограничено? - person Joe; 20.10.2016