模糊覆盖不覆盖整个屏幕
Blurred overlay does not cover entire screen
我正在尝试在包含 UITableView 并以模态方式显示的 ViewController 上显示模糊背景。 但我似乎无法获得覆盖整个屏幕的模糊效果,特别是导航栏和状态栏。下面是覆盖导航栏下方区域的模糊效果的屏幕截图,但是不高于它——当我将 UIVisualEffectView 的框架设置为 view.bounds 时会发生这种情况。 (注意:模糊效果设计为与带键盘的标题屏幕同时显示,并且标题屏幕具有清晰的+ non-opaque背景以适应这种模糊效果。)
有趣的是,当我将 UIVisualEffectView 的 frame 设置为 view.frame(而不是 view.bounds)时,模糊效果仅覆盖大约 2/3rds view.bound 覆盖的区域。不确定为什么要这样做。
下面是我的代码。如您所见,按下 'Done' 按钮时,应用会生成 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
。就frame而言,只需添加右约束,它就会自动布局(无需设置frame),例如,如果您希望模糊视图覆盖整个屏幕,您可以添加这些约束。
在ActionViewController
的viewDidLoad
函数中调用这个函数
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
}
首先,穆罕默德的建议应该有效。您的代码崩溃的原因可能是您试图在将 blurView
作为子视图添加到您的视图之前先添加约束。关键词是:
they have no common ancestor.
不要那样做。在约束它之前总是添加你的子视图。
最后,实现您想要实现的目标的一种简单方法是,只要在显示透明屏幕(带键盘的屏幕)时切换导航栏的可见性,然后在完成后将导航栏恢复可见.像这样:
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()
}
}
}
我正在尝试在包含 UITableView 并以模态方式显示的 ViewController 上显示模糊背景。 但我似乎无法获得覆盖整个屏幕的模糊效果,特别是导航栏和状态栏。下面是覆盖导航栏下方区域的模糊效果的屏幕截图,但是不高于它——当我将 UIVisualEffectView 的框架设置为 view.bounds 时会发生这种情况。 (注意:模糊效果设计为与带键盘的标题屏幕同时显示,并且标题屏幕具有清晰的+ non-opaque背景以适应这种模糊效果。)
有趣的是,当我将 UIVisualEffectView 的 frame 设置为 view.frame(而不是 view.bounds)时,模糊效果仅覆盖大约 2/3rds view.bound 覆盖的区域。不确定为什么要这样做。
下面是我的代码。如您所见,按下 'Done' 按钮时,应用会生成 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
。就frame而言,只需添加右约束,它就会自动布局(无需设置frame),例如,如果您希望模糊视图覆盖整个屏幕,您可以添加这些约束。
在ActionViewController
的viewDidLoad
函数中调用这个函数
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
}
首先,穆罕默德的建议应该有效。您的代码崩溃的原因可能是您试图在将 blurView
作为子视图添加到您的视图之前先添加约束。关键词是:
they have no common ancestor.
不要那样做。在约束它之前总是添加你的子视图。
最后,实现您想要实现的目标的一种简单方法是,只要在显示透明屏幕(带键盘的屏幕)时切换导航栏的可见性,然后在完成后将导航栏恢复可见.像这样:
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()
}
}
}