UIAlertController 更改操作取消按钮的背景颜色 sheet
UIAlertController change background color of Cancel button for action sheet
我正在尝试创建具有动作 sheet 样式的 UIAlertController,但我想将背景颜色更改为灰色。我已经能够找到一种方法来更改 UIAlertController 的背景颜色,但不能更改“取消”按钮。单独的“取消”按钮保持白色。
这是我现在拥有的代码:
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 1" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 2" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 3" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
UIView *firstSubview = alert.view.subviews.firstObject;
UIView *alertContentView = firstSubview.subviews.firstObject;
for (UIView *subSubView in alertContentView.subviews) {
subSubView.backgroundColor = [UIColor darkGrayColor]; // Here you change background
}
alert.view.tintColor = [UIColor whiteColor];
[self.controller presentViewController:alert animated:YES completion:nil];
这给了我以下结果:
Link
我去过如何改变UIAlertController的背景颜色?
但 none 的解决方案为“取消”按钮的背景设置了自定义颜色。
如有任何帮助,我们将不胜感激!
我现在找到了解决方案。我创建了示例项目并解决了您的问题,我明白了。
ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 1" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 2" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 3" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
UIView *subView = alert.view.subviews.lastObject; //firstObject
UIView *alertContentView = subView.subviews.lastObject; //firstObject
[alertContentView setBackgroundColor:[UIColor darkGrayColor]];
alertContentView.layer.cornerRadius = 5;
[self presentViewController:alert animated:YES completion:nil];
alert.view.tintColor = [UIColor darkGrayColor];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
查看输出
如果您想要一个单独的取消按钮 (UIAlertActionStyleCancel),则不能更改取消按钮的背景颜色。如果这是您的首要任务,那么您必须制作自己的自定义视图。或者您可以简单地添加标题为 "Cancel".
的默认操作
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil]]
(但它不会给你一个单独的按钮)。
有一个非常非常肮脏的解决方案,但它有效。为此,我们将使用 UIAppearance。
首先,我们需要为 UIView 准备一个特殊的私有扩展,以便能够更改其子视图的背景颜色。
fileprivate extension UIView {
private struct AssociatedKey {
static var subviewsBackgroundColor = "subviewsBackgroundColor"
}
@objc dynamic var subviewsBackgroundColor: UIColor? {
get {
return objc_getAssociatedObject(self, &AssociatedKey.subviewsBackgroundColor) as? UIColor
}
set {
objc_setAssociatedObject(self,
&AssociatedKey.subviewsBackgroundColor,
newValue,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
subviews.forEach { [=10=].backgroundColor = newValue }
}
}
}
每次我们设置 subiewsBackgroundColor 值时,UIView 将迭代它的子视图并为每个子视图设置新的背景颜色。
正如您在下面的答案中看到的那样,在 UIAlertController 的层次结构中有一个名为 _UIAlertControlleriOSActionSheetCancelBackgroundView 的特殊 UIView,它包含一个白色的子视图(用于取消按钮)
让我们尝试获得它的外观并使用我们的 属性 来改变它的子视图颜色。我想这是一种私人 api.
if let cancelBackgroundViewType = NSClassFromString("_UIAlertControlleriOSActionSheetCancelBackgroundView") as? UIView.Type {
cancelBackgroundViewType.appearance().subviewsBackgroundColor = .red
}
将此代码放在 AppDelegate 的 didFinishLaunching 或专用 class 中。
而已。现在您可以在红色背景上看到取消按钮。在 iOS 11.
上测试
您不能更改默认取消按钮样式的颜色。您需要为取消按钮创建一个自定义视图控制器,并将其设置为取消警报操作的内容视图控制器。这样单独保留取消按钮
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "Option 1", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Option 2", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Option 3", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: nil))
if let firstSubview = alertController.view.subviews.first, let alertContentView = firstSubview.subviews.first {
for view in alertContentView.subviews {
view.backgroundColor = .darkGray
}
}
alertController.view.tintColor = .white
let cancelButtonViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CancelButtonViewController")
let cancelAction = UIAlertAction(title: "", style: .cancel, handler: nil)
cancelAction.setValue(cancelButtonViewController, forKey: "contentViewController")
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
我在我的混合 Objective-C / Swift 项目中使用了 answer by mbryzinski,并且能够像这样修改 Objective-C 的取消按钮背景颜色:
((UIView *)[NSClassFromString(@"_UIAlertControlleriOSActionSheetCancelBackgroundView")
appearance]).subviewsBackgroundColor = [UIColor yourBackgroundColor];
我将 UIView 扩展作为 .swift 文件包含在项目中,我不得不 删除 fileprivate 关键字:
extension UIView {
private struct AssociatedKey {
static var subviewsBackgroundColor = "subviewsBackgroundColor"
}
@objc dynamic var subviewsBackgroundColor: UIColor? {
...
此外,需要在使用扩展名的文件中导入桥接 header:
#import "{Your Project's name}-Swift.h"
修改 UIAlertController 的背景和文本颜色是实现深色主题的一种快速(而且确实很脏)的方法。
圆角周围有一些轻微的伪影,背景颜色越深,变得越明显。特别是在 iPad 上,伪影非常明显。
正确的解决方案可能是使用自定义警报控制器。 (还没有找到一个看起来很像库存的。)
我正在尝试创建具有动作 sheet 样式的 UIAlertController,但我想将背景颜色更改为灰色。我已经能够找到一种方法来更改 UIAlertController 的背景颜色,但不能更改“取消”按钮。单独的“取消”按钮保持白色。
这是我现在拥有的代码:
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 1" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 2" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 3" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
UIView *firstSubview = alert.view.subviews.firstObject;
UIView *alertContentView = firstSubview.subviews.firstObject;
for (UIView *subSubView in alertContentView.subviews) {
subSubView.backgroundColor = [UIColor darkGrayColor]; // Here you change background
}
alert.view.tintColor = [UIColor whiteColor];
[self.controller presentViewController:alert animated:YES completion:nil];
这给了我以下结果: Link
我去过如何改变UIAlertController的背景颜色? 但 none 的解决方案为“取消”按钮的背景设置了自定义颜色。
如有任何帮助,我们将不胜感激!
我现在找到了解决方案。我创建了示例项目并解决了您的问题,我明白了。
ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 1" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 2" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Option 3" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
UIView *subView = alert.view.subviews.lastObject; //firstObject
UIView *alertContentView = subView.subviews.lastObject; //firstObject
[alertContentView setBackgroundColor:[UIColor darkGrayColor]];
alertContentView.layer.cornerRadius = 5;
[self presentViewController:alert animated:YES completion:nil];
alert.view.tintColor = [UIColor darkGrayColor];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
查看输出
如果您想要一个单独的取消按钮 (UIAlertActionStyleCancel),则不能更改取消按钮的背景颜色。如果这是您的首要任务,那么您必须制作自己的自定义视图。或者您可以简单地添加标题为 "Cancel".
的默认操作[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil]]
(但它不会给你一个单独的按钮)。
有一个非常非常肮脏的解决方案,但它有效。为此,我们将使用 UIAppearance。
首先,我们需要为 UIView 准备一个特殊的私有扩展,以便能够更改其子视图的背景颜色。
fileprivate extension UIView {
private struct AssociatedKey {
static var subviewsBackgroundColor = "subviewsBackgroundColor"
}
@objc dynamic var subviewsBackgroundColor: UIColor? {
get {
return objc_getAssociatedObject(self, &AssociatedKey.subviewsBackgroundColor) as? UIColor
}
set {
objc_setAssociatedObject(self,
&AssociatedKey.subviewsBackgroundColor,
newValue,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
subviews.forEach { [=10=].backgroundColor = newValue }
}
}
}
每次我们设置 subiewsBackgroundColor 值时,UIView 将迭代它的子视图并为每个子视图设置新的背景颜色。
正如您在下面的答案中看到的那样,在 UIAlertController 的层次结构中有一个名为 _UIAlertControlleriOSActionSheetCancelBackgroundView 的特殊 UIView,它包含一个白色的子视图(用于取消按钮)
让我们尝试获得它的外观并使用我们的 属性 来改变它的子视图颜色。我想这是一种私人 api.
if let cancelBackgroundViewType = NSClassFromString("_UIAlertControlleriOSActionSheetCancelBackgroundView") as? UIView.Type {
cancelBackgroundViewType.appearance().subviewsBackgroundColor = .red
}
将此代码放在 AppDelegate 的 didFinishLaunching 或专用 class 中。 而已。现在您可以在红色背景上看到取消按钮。在 iOS 11.
上测试您不能更改默认取消按钮样式的颜色。您需要为取消按钮创建一个自定义视图控制器,并将其设置为取消警报操作的内容视图控制器。这样单独保留取消按钮
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "Option 1", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Option 2", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Option 3", style: .default, handler: nil))
alertController.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: nil))
if let firstSubview = alertController.view.subviews.first, let alertContentView = firstSubview.subviews.first {
for view in alertContentView.subviews {
view.backgroundColor = .darkGray
}
}
alertController.view.tintColor = .white
let cancelButtonViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CancelButtonViewController")
let cancelAction = UIAlertAction(title: "", style: .cancel, handler: nil)
cancelAction.setValue(cancelButtonViewController, forKey: "contentViewController")
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
我在我的混合 Objective-C / Swift 项目中使用了 answer by mbryzinski,并且能够像这样修改 Objective-C 的取消按钮背景颜色:
((UIView *)[NSClassFromString(@"_UIAlertControlleriOSActionSheetCancelBackgroundView")
appearance]).subviewsBackgroundColor = [UIColor yourBackgroundColor];
我将 UIView 扩展作为 .swift 文件包含在项目中,我不得不 删除 fileprivate 关键字:
extension UIView {
private struct AssociatedKey {
static var subviewsBackgroundColor = "subviewsBackgroundColor"
}
@objc dynamic var subviewsBackgroundColor: UIColor? {
...
此外,需要在使用扩展名的文件中导入桥接 header:
#import "{Your Project's name}-Swift.h"
修改 UIAlertController 的背景和文本颜色是实现深色主题的一种快速(而且确实很脏)的方法。 圆角周围有一些轻微的伪影,背景颜色越深,变得越明显。特别是在 iPad 上,伪影非常明显。
正确的解决方案可能是使用自定义警报控制器。 (还没有找到一个看起来很像库存的。)