问题描述
我试图在包含UITableView并以模态显示的ViewController上显示模糊的背景。 但是我似乎无法获得覆盖整个屏幕的模糊效果,尤其是导航栏和状态栏。下面是覆盖导航栏下方但不覆盖上方的模糊效果的屏幕截图-当我将UIVisualEffectView的框架设置为 view.bounds 时,就会发生这种情况。 (注意:模糊效果被设计为与带有键盘的标题屏幕同时显示,并且标题屏幕具有透明+不透明的背景以适应这种模糊效果。)
有趣的是,当我将UIVisualEffectView的框架设置为 view.frame (而不是view.bounds)时,模糊效果仅覆盖view.bound所覆盖区域的约2 / 3rds。不知道为什么要这么做。
下面是代码中的内容。如您所见,当按下“完成”按钮时,应用程序会生成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)
}
解决方法
您需要将模糊叠加视图放置在显示的视图控制器中,而不是显示视图控制器,即ActionViewController
。就框架而言,只需添加正确的约束,它将自动进行布局(无需设置框架),例如,如果您希望模糊视图覆盖整个屏幕,则可以添加这些约束。
在viewDidLoad
的{{1}}函数中调用此函数
ActionViewController
,
首先,穆罕默德的建议应该起作用。代码崩溃的原因可能是您在将blurView
作为子视图添加到视图之前先尝试添加约束。关键短语是:
他们没有共同的祖先。
不要那样做。始终在约束前添加子视图。
最后,一种实现所需目标的简单方法是,每当您显示透明屏幕(带有键盘的屏幕)时,就可以切换NavigationBar的可见性,然后在完成时将NavigationBar重新显示为可见。像这样:
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()
}
}
}