2017-06-17 318 views
0

我想创建一个具有操作表样式的UIAlertController,但我想将背景颜色更改为灰色。我已经能够找到一种方法来改变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

我曾参观过How to change the background color of the UIAlertController? 但没有任何解决方案都为自定义颜色取消按钮的背景。

任何帮助,将不胜感激!

+0

是否要更改取消按钮的背景颜色? – user3182143

+0

查看我的编码我将取消按钮颜色更改为darkGray颜色。 – user3182143

+0

我希望取消按钮具有深灰色背景色和白色文本。你的代码似乎没有这样做,但是相反:你的取消按钮的背景颜色是白色的,而你的文本颜色是灰色的 – Pibomb

回答

0

我现在得到了解决方案。我创建了示例项目,并为您的问题制定了解决方案,并且获得了它。

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 

看到输出

enter image description here

+1

我认为你没有正确理解我的问题。取消按钮的背景颜色仍然是白色,并且您的文本现在变成灰色。我需要相反的事情发生 – Pibomb

4

如果你想要一个单独取消按钮(UIAlertActionStyleCancel)你不能更改取消按钮的背景颜色。如果这是你的优先,那么你必须做出自己的自定义视图。否则,您可以简单地添加标题为“取消”的默认操作。

[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil]]

(但它不会给你一个单独的按钮)。

我调试了视图层次结构,发现这一点。 enter image description here

0

有一个非常非常肮脏的解决方案,但它的工作原理。为此,我们将使用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 { $0.backgroundColor = newValue } 
     } 
    } 
} 

我们每次设定subiewsBackgroundColor值的UIView会遍历它的子视图,并为每一个新的背景颜色。

正如你可以在答案见下面有一个叫_UIAlertControlleriOSActionSheetCancelBackgroundView在UIAlertController的层次结构特殊的UIView其中包含与白色颜色的子视图(Cancel按钮)

让我们试着去得到它的外观和使用我们的属性来改变它的子视图颜色。我想这是一种私人API。

if let cancelBackgroundViewType = NSClassFromString("_UIAlertControlleriOSActionSheetCancelBackgroundView") as? UIView.Type { 
    cancelBackgroundViewType.appearance().subviewsBackgroundColor = .red 
} 

将此代码放在AppDelegate的didFinishLaunching或专用类中。 就是这样。现在您可以看到红色背景上的取消按钮。在iOS 11上测试。