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

#ios #swift #uiviewcontroller #uiblureffect

#iOS #swift #uiviewcontroller #uiblureffect

Вопрос:

У меня есть несколько вкладок в моем приложении ( 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)
  

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

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

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

Серый фон

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

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

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

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

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

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

Ответ №1:

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

Первый VC

    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

    }
   }
  }
  

SecondVC

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

}

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

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

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

Комментарии:

1. спасибо, но я не уверен, что это имеет отношение к моей проблеме. в вашем примере у вас есть два отдельных viewcontroller с размытым фоном (и это работает, очевидно, потому что любой из них будет перерисован). в моем случае у меня один viewcontroller поверх другого (и этот viewcontroller за размытым не перерисовывается).

2. Теперь я понял. вы должны упомянуть, что вы используете UITabBarController. не 2 ViewController перекрывают друг друга.

3. нет, этот код взят из примера проекта. я не передаю никаких данных между этими контроллерами (за исключением «bVC.modalPresentationStyle = .overCurrentContext», как вы можете видеть в моих фрагментах кода).

4. Я понимаю. Теперь ваша проблема решается еще проще…. вы знаете, вы все еще можете использовать мой ответ. применима та же логика…

5. нет, у моего item1 есть какая-то кнопка. при нажатии на эту кнопку будет показан uiviewcontroller (с размытым видом внутри).