没有模糊视图效果的UIAlertController操作表 [英] UIAlertController Action Sheet without Blurry View Effect
问题描述
我正在使用UIAlertController
进行某些操作.
I'm using UIAlertController
for some actions.
但是我不喜欢动作组视图中的模糊视图效果(请参见下面的屏幕截图).
But I'm not a big fan of the Blurry View Effect in the actions group view (see screenshot below).
我正在尝试消除这种模糊效果.我在网上进行了一些研究,但在UIAlertController
中找不到任何可以消除这种模糊效果的API.另外,根据他们的Apple文档此处:
I'm trying to remove this blurry effect. I made some research online, and I couldn't find any API in UIAlertController
that allows to remove this blurry effect. Also, according to their apple doc here :
UIAlertController类旨在按原样使用,并且不支持子类化.此类的视图层次结构是私有的,不能修改.
The UIAlertController class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.
我看到Instagram也消除了这种模糊的视图效果:
I see that Instagram also removes this blurry view effect :
我唯一可以删除它的方法是通过扩展名UIAlertController
自己更新视图层次结构.
The only way I could find to remove it is to update the view hierarchy myself via an extension of UIAlertController
.
extension UIAlertController {
@discardableResult private func findAndRemoveBlurEffect(currentView: UIView) -> Bool {
for childView in currentView.subviews {
if childView is UIVisualEffectView {
childView.removeFromSuperview()
return true
} else if String(describing: type(of: childView.self)) == "_UIInterfaceActionGroupHeaderScrollView" {
// One background view is broken, we need to make sure it's white.
if let brokenBackgroundView = childView.superview {
// Set broken brackground view to a darker white
brokenBackgroundView.backgroundColor = UIColor.colorRGB(red: 235, green: 235, blue: 235, alpha: 1)
}
}
findAndRemoveBlurEffect(currentView: childView)
}
return false
}
}
let actionSheetController = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
actionSheetController.view.tintColor = .lightBlue
actionSheetController.removeBlurryView()
这很好用,它消除了我模糊的视图效果:
This worked fine, it removed my blurry view effect:
我想知道的是...解决方案是实现此目标的唯一方法吗?还是我缺少有关警报控制器外观的信息? 也许有一种更干净的方法来准确地实现该结果?还有其他想法吗?
What I'm wondering... Is my solution the only way to accomplish that? Or there is something that I'm missing about the Alert Controller appearance? Maybe there is a cleaner way to accomplish exactly that result? Any other ideas?
推荐答案
子类
It is easier to subclass UIAlertController
.
想法是每次调用viewDidLayoutSubviews
时都要遍历视图层次结构,删除UIVisualEffectView
的效果并更新其backgroundColor
:
The idea is to traverse through view hierarchy each time viewDidLayoutSubviews
gets called, remove effect for UIVisualEffectView
's and update their backgroundColor
:
class AlertController: UIAlertController {
/// Buttons background color.
var buttonBackgroundColor: UIColor = .darkGray {
didSet {
// Invalidate current colors on change.
view.setNeedsLayout()
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Traverse view hierarchy.
view.allViews.forEach {
// If there was any non-clear background color, update to custom background.
if let color = $0.backgroundColor, color != .clear {
$0.backgroundColor = buttonBackgroundColor
}
// If view is UIVisualEffectView, remove it's effect and customise color.
if let visualEffectView = $0 as? UIVisualEffectView {
visualEffectView.effect = nil
visualEffectView.backgroundColor = buttonBackgroundColor
}
}
// Update background color of popoverPresentationController (for iPads).
popoverPresentationController?.backgroundColor = buttonBackgroundColor
}
}
extension UIView {
/// All child subviews in view hierarchy plus self.
fileprivate var allViews: [UIView] {
var views = [self]
subviews.forEach {
views.append(contentsOf: $0.allViews)
}
return views
}
}
用法:
- 创建警报控制器.
- 设置按钮的背景色:
alertController.buttonBackgroundColor = .darkGray
- 自定义并显示控制器.
- Create alert controller.
- Set buttons background color:
alertController.buttonBackgroundColor = .darkGray
- Customise and present controller.
结果:
这篇关于没有模糊视图效果的UIAlertController操作表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!