Размытое наложение не покрывает весь экран

#ios #swift #frontend #uivisualeffectview #uiblureffect

#iOS #swift #интерфейс #uivisualeffectview #uiblureffect

Вопрос:

Я пытаюсь отобразить размытый фон поверх ViewController, который содержит UITableView и отображается модально. Но, похоже, я не могу добиться эффекта размытия, чтобы он покрывал весь экран, в частности навигацию и строки состояния.Ниже приведен скриншот эффекта размытия, покрывающего область под панелью навигации, но не над ней — это происходит, когда я устанавливаю рамку UIVisualEffectView в view.bounds. (Примечание: Эффект размытия предназначен для отображения одновременно с экраном заголовка с клавиатурой, а экран заголовка имеет прозрачный непрозрачный фон для соответствия этому эффекту размытия.)

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

Интересно, что когда я устанавливаю рамку UIVisualEffectView на view.frame (а не view.bounds), эффект размытия покрывает только около 2/3 области, которую покрывает view.bound. Не уверен, почему он это делает.

Ниже приведено то, что у меня есть в моем коде. Как вы можете видеть, при нажатии кнопки «Готово» приложение генерирует ActionViewController (экран заголовка) вместе с размытым фоном, который вызывается через метод делегирования.

 @IBAction func donePressed(_ sender: UIButton) {
    let vc = ActionViewController()
    self.definesPresentationContext = true
    self.providesPresentationContextTransitionStyle = true
    vc.modalPresentationStyle = .overFullScreen
    vc.modalTransitionStyle = .coverVertical
    
    self.present(vc, animated: true, completion: nil)
    self.overlayBlurredBackgroundView()
    vc.delegate = self
}

extension PreviewViewController: ActionViewControllerDelegate {
    func overlayBlurredBackgroundView() {
        let blurredBackgroundView = UIVisualEffectView()
        blurredBackgroundView.frame = view.bounds
        blurredBackgroundView.effect = UIBlurEffect(style: .systemThinMaterialDark)
        view.addSubview(blurredBackgroundView)
}
  

Ответ №1:

Во-первых, то, что предложил Мухаммед, должно сработать. Причиной сбоя вашего кода может быть то, что вы пытаетесь сначала добавить ограничения, прежде чем добавлять blurView в свой вид в качестве подвида. Ключевая фраза:

у них нет общего предка.

Не делайте этого. Всегда добавляйте свой вложенный просмотр, прежде чем ограничивать его.


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

 func overlayBlurredBackgroundView() {
  self.navigationController?.navigationBar.isHidden = true
  
    let blurredBackgroundView = UIVisualEffectView()
    //blurredBackgroundView.frame = view.bounds
    blurredBackgroundView.effect = UIBlurEffect(style: .systemThinMaterialDark)
    view.addSubview(blurredBackgroundView)
  
    blurredBackgroundView.translatesAutoresizingMaskIntoConstraints = false
    blurredBackgroundView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0.0).isActive = true
    blurredBackgroundView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0.0).isActive = true
    blurredBackgroundView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0.0).isActive = true
    blurredBackgroundView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0.0).isActive = true

}
  

а затем возвращает его обратно, когда вы его удаляете:

 func removeBlurredBackgroundView() {
  self.navigationController?.navigationBar.isHidden = false
    for subview in view.subviews {
        if subview.isKind(of: UIVisualEffectView.self) {
            subview.removeFromSuperview()
        }
    }
}
  

Ответ №2:

Вам нужно поместить вид наложения размытия в представленный контроллер представления вместо представления контроллера представления, т. Е. ActionViewController . Что касается рамки, просто добавьте правильное ограничение, и оно будет автоматически размещено (нет необходимости устанавливать рамку), например, если вы хотите, чтобы ваш вид размытия охватывал весь экран, вы можете добавить эти ограничения.

В viewDidLoad функции ActionViewController вызовите эту функцию

 func addOverlayBlurredBackgroundView() {
    let blurView = UIVisualEffectView()
    blurView.effect = UIBlurEffect(style: .systemThinMaterialDark)
    self.view.insertSubview(blurView, at: 0)

    blurView.translatesAutoresizingMaskIntoConstraints = false

    blurView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0.0).isActive = true
    blurView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0.0).isActive = true
    blurView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0.0).isActive = true
    blurView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0.0).isActive = true
}
  

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

1. Привет, Мухаммад. Я действительно помещаю размытое наложение в представленный контроллер просмотра (т. Е. PreviewViewController, а не ActionViewController). Когда я добавляю ограничения, как вы предлагаете, приложение выходит из строя и отображает сообщение «Невозможно активировать ограничение с помощью якорей, потому что у них нет общего предка. Ссылается ли ограничение или его привязки на элементы в разных иерархиях представлений? Это незаконно «.

2. да! я предлагаю вам поместить вид размытия в ActionViewController . Из вашего кода я вижу, что вы представляете ActionViewController затем добавляете размытое изображение в контроллер предварительного просмотра. Контроллер предварительного просмотра находится в контроллере навигации, и все, что вы добавите в его представление, останется под панелью навигации.

3. Я вижу. Я попытался ввести размытое представление в виде рамки в функции loadView в ActionViewController, но, похоже, оно не появляется. Есть предложения о том, как это сделать? Кроме того, использование ограничений будет продолжать генерировать ошибку, о которой я упоминал ранее.