ios 如何更改 UIAlertController 的背景颜色?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26863460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change the background color of the UIAlertController?
提问by GJDK
Due to strange behavior of UIActionSheet in iOS 8, I have implemented UIAlertController with UIAction as buttons in it. I would like to change the entire background of the UIAlertController. But I can't find any ways to do it.
由于 iOS 8 中 UIActionSheet 的奇怪行为,我已经实现了 UIAlertController 和 UIAction 作为其中的按钮。我想更改 UIAlertController 的整个背景。但我找不到任何方法来做到这一点。
Tried even with,
甚至尝试过,
actionController.view.backgroundColor = [UIColor blackColor];
But didn't help me out. Any inputs on this regard will be appreciable.
但没有帮助我。在这方面的任何投入都将是可观的。
Thanks in advance.
提前致谢。
回答by nischtname
You have to step some views deeper:
您必须更深入地了解一些视图:
let subview = actionController.view.subviews.first! as UIView
let alertContentView = subview.subviews.first! as UIView
alertContentView.backgroundColor = UIColor.blackColor()
And maybe you want to keep original corner radius:
也许你想保持原来的圆角半径:
alertContentView.layer.cornerRadius = 5;
Sorry for the "Swifting"but i'm not familiar with Objective-C. I hope that's similar.
对不起“Swifting”,但我不熟悉Objective-C。我希望这是相似的。
Of course it's also important to change the title color of the actions. Unfortunately I don't know, how to set the color of actions separately. But this is, how you change all button text colors:
当然,改变动作的标题颜色也很重要。不幸的是,我不知道如何分别设置动作的颜色。但这是,如何更改所有按钮文本颜色:
actionController.view.tintColor = UIColor.whiteColor();
EDIT:
编辑:
The corner radius of the UIAlertControllerhas changed since this answer's been posted! Replace this:
自从发布此答案以来,UIAlertController的角半径已更改!替换这个:
alertContentView.layer.cornerRadius = 5;
to this:
对此:
actionContentView.layer.cornerRadius = 15
回答by Jeanette Müller
maybe you like the use the blur effect in the dark mode. Here is a very easy way to get this:
也许你喜欢在黑暗模式下使用模糊效果。这是一个非常简单的方法来获得它:
UIVisualEffectView.appearance(whenContainedInInstancesOf: [UIAlertController.classForCoder() as! UIAppearanceContainer.Type]).effect = UIBlurEffect(style: .dark)
回答by Bruno Philipe
I have found a hack-ish way of doing it. First you need an extension to allow you to search for the UIVisualEffectView
inside the UIAlertController
:
我找到了一种黑客式的方法。首先,你需要的扩展,使您可以搜索UIVisualEffectView
里面的UIAlertController
:
extension UIView
{
func searchVisualEffectsSubview() -> UIVisualEffectView?
{
if let visualEffectView = self as? UIVisualEffectView
{
return visualEffectView
}
else
{
for subview in subviews
{
if let found = subview.searchVisualEffectsSubview()
{
return found
}
}
}
return nil
}
}
Important: You have to call this function aftercalling presentViewController
, because only after loading the view controller that the visual effects view is inserted into place. Then you can change the effect associated with it to a dark blur effect:
重要提示:您必须在调用后调用此函数presentViewController
,因为只有在加载视图控制器后,视觉效果视图才会插入到位。然后您可以将与之关联的效果更改为暗模糊效果:
self.presentViewController(actionController, animated: true, completion: nil)
if let visualEffectView = actionController.view.searchVisualEffectsSubview()
{
visualEffectView.effect = UIBlurEffect(style: .Dark)
}
And this is the final result:
这是最终的结果:
I am honestly surprised myself how well it works! I think this is probably something Apple forgot to add. Also, I haven't yetpassed an App through approval with this "hack" (it isn't a hack because we're only using public APIs), but I'm confident there won't be a problem.
老实说,我自己很惊讶它的效果如何!我认为这可能是 Apple 忘记添加的内容。此外,我还没有还没有通过这个“黑客”(这是不是黑客攻击,因为我们只使用公共API)批准通过了一个应用程序,但我相信不会有问题。
回答by Shakeel Ahmed
回答by Mark Bourke
Here is a UIAlertController
extension that works on both iPad and iPhone. Cancel button will change from a dark colour to white automatically depending on what blurStyle is selected:
这是一个UIAlertController
适用于 iPad 和 iPhone的扩展程序。取消按钮会根据选择的 blurStyle 自动从深色变为白色:
extension UIAlertController {
private struct AssociatedKeys {
static var blurStyleKey = "UIAlertController.blurStyleKey"
}
public var blurStyle: UIBlurEffectStyle {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.blurStyleKey) as? UIBlurEffectStyle ?? .extraLight
} set (style) {
objc_setAssociatedObject(self, &AssociatedKeys.blurStyleKey, style, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
view.setNeedsLayout()
view.layoutIfNeeded()
}
}
public var cancelButtonColor: UIColor? {
return blurStyle == .dark ? UIColor(red: 28.0/255.0, green: 28.0/255.0, blue: 28.0/255.0, alpha: 1.0) : nil
}
private var visualEffectView: UIVisualEffectView? {
if let presentationController = presentationController, presentationController.responds(to: Selector(("popoverView"))), let view = presentationController.value(forKey: "popoverView") as? UIView // We're on an iPad and visual effect view is in a different place.
{
return view.recursiveSubviews.flatMap({extension UIView {
var recursiveSubviews: [UIView] {
var subviews = self.subviews.flatMap({let controller = UIAlertController(title: "Dark Alert Controller", message: nil, preferredStyle: .actionSheet, blurStyle: .dark)
// Setup controller actions etc...
present(controller, animated: true, completion: nil)
})
subviews.forEach { subviews.append(contentsOf: let subview1 = alert.view.subviews.first! as UIView
let subview2 = subview1.subviews.first! as UIView
let view = subview2.subviews.first! as UIView
subview.backgroundColor = backgroundColor
view.backgroundColor = backgroundColor
view.layer.cornerRadius = 10.0
// set color to UILabel font
setSubviewLabelsToTextColor(textColor, view: view)
// set font to alert via KVC, otherwise it'll get overwritten
let titleAttributed = NSMutableAttributedString(
string: alert.title!,
attributes: [NSFontAttributeName:UIFont.boldSystemFont(ofSize: 17)])
alert.setValue(titleAttributed, forKey: "attributedTitle")
let messageAttributed = NSMutableAttributedString(
string: alert.message!,
attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: 13)])
alert.setValue(messageAttributed, forKey: "attributedMessage")
// set the buttons to non-blue, if we have buttons
if let buttonColor = buttonColor {
alert.view.tintColor = buttonColor
}
.recursiveSubviews) }
return subviews
}
}
as? UIVisualEffectView}).first
}
return view.recursiveSubviews.flatMap({func Alert(View: ViewController, Title: String, TitleColor: UIColor, Message: String, MessageColor: UIColor, BackgroundColor: UIColor, BorderColor: UIColor, ButtonColor: UIColor) {
let TitleString = NSAttributedString(string: Title, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(15), NSForegroundColorAttributeName : TitleColor])
let MessageString = NSAttributedString(string: Message, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(15), NSForegroundColorAttributeName : MessageColor])
let alertController = UIAlertController(title: Title, message: Message, preferredStyle: .Alert)
alertController.setValue(TitleString, forKey: "attributedTitle")
alertController.setValue(MessageString, forKey: "attributedMessage")
let okAction = UIAlertAction(title: "OK", style: .Default) { (action) in
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
alertController.addAction(okAction)
alertController.addAction(cancelAction)
let subview = alertController.view.subviews.first! as UIView
let alertContentView = subview.subviews.first! as UIView
alertContentView.backgroundColor = BackgroundColor
alertContentView.layer.cornerRadius = 10
alertContentView.alpha = 1
alertContentView.layer.borderWidth = 1
alertContentView.layer.borderColor = BorderColor.CGColor
//alertContentView.tintColor = UIColor.whiteColor()
alertController.view.tintColor = ButtonColor
View.presentViewController(alertController, animated: true) {
// ...
}
}
as? UIVisualEffectView}).first
}
private var cancelActionView: UIView? {
return view.recursiveSubviews.flatMap({
UIAlertController * alert=[UIAlertController alertControllerWithTitle:@"Title"
message:@"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIView *firstSubview = alert.view.subviews.firstObject;
UIView *alertContentView = firstSubview.subviews.firstObject;
for (UIView *subSubView in alertContentView.subviews) {
subSubView.backgroundColor = [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f];
}
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
//Close Action
}];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
as? UILabel}
).first(where: {
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 = [[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setBackgroundColor:[UIColor blackColor]];
.backgroundColor, color != .clear {
##代码##.backgroundColor = buttonBackgroundColor
}
// If view is UIVisualEffectView, remove it's effect and customise color.
if let visualEffectView = ##代码## 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: ##代码##.allViews)
}
return views
}
}
.text == actions.first(where: { ##代码##.style == .cancel })?.title
})?.superview?.superview
}
public convenience init(title: String?, message: String?, preferredStyle: UIAlertControllerStyle, blurStyle: UIBlurEffectStyle) {
self.init(title: title, message: message, preferredStyle: preferredStyle)
self.blurStyle = blurStyle
}
open override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
visualEffectView?.effect = UIBlurEffect(style: blurStyle)
cancelActionView?.backgroundColor = cancelButtonColor
}
}
The following UIView
extension is also needed:
UIView
还需要以下扩展:
Example:
例子:
##代码##iPhone:
苹果手机:
iPad:
iPad:
回答by Leandro Jiao
Swift3
斯威夫特3
Step into one more layer compare with swift2
与swift2相比,再进一层
##代码##回答by user2643679
回答by Yogesh Tarsariya
For Objective - C Code May be Like.
对于目标 - C 代码可能就像。
##代码##回答by Bandyliuk
The best decision that i found (without white spots on the sides)
我发现的最佳决定(两侧没有白点)
Link to original answerby Vadim Akhmerov
Answer:
回答:
It is easier to subclass UIAlertController
.
子类化更容易UIAlertController
。
The idea is to traverse through view hierarchy each time viewDidLayoutSubviews
gets called, remove effect for UIVisualEffectView
's and update their backgroundColor
:
这个想法是在每次viewDidLayoutSubviews
被调用时遍历视图层次结构,删除UIVisualEffectView
's 的效果并更新它们backgroundColor
:
Usage:
用法:
- Create alert controller(use now AlertController instead UIAlertController)
- 创建警报控制器(现在使用 AlertController 而不是 UIAlertController)
let testAlertController = AlertController(title: nil, message: nil, preferredStyle: .actionSheet)
让 testAlertController = AlertController(title: nil, message: nil, preferredStyle: .actionSheet)
- Set background color on custom class "AlertController":
- 在自定义类“AlertController”上设置背景颜色:
var buttonBackgroundColor: UIColor = .darkGray
var buttonBackgroundColor: UIColor = .darkGray
回答by Paul Kite
You can use the appearance proxy.
您可以使用外观代理。
##代码##This seems to apply for all but the cancel action when presenting as an action sheet.
当作为操作表呈现时,这似乎适用于除取消操作之外的所有操作。