UIAlertController改变取消按钮的背景颜色动作片

问题描述 投票:1回答:5

我试图创建一个与动作片的风格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? 但没有任何解决方案都具有Cancel按钮的背景自定义颜色。

任何帮助,将不胜感激!

ios objective-c uialertcontroller
5个回答
4
投票

您不能更改默认的颜色款式取消按钮。你需要创建一个取消按钮自定义视图控制器,并将其设置为取消警报措施的内容视图控制器。这样,分别保持了取消按钮

enter image description here

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)

enter image description here


5
投票

有一个非常非常肮脏的解决方案,但它的工作原理。我们将使用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会遍历它的子视图,并为每一个新的背景颜色。

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

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

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

放置在AppDelegate中的didFinishLaunching该代码或专用类。而已。现在你可以看到取消红色背景按钮。经测试在iOS上11。


3
投票

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

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

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

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


1
投票

我使用answermbryzinski我在混合的Objective-C /斯威夫特项目,并能够从这样的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? {
    ...

此外,桥接报头需要在使用扩展名的文件中要导入:

#import "{Your Project's name}-Swift.h"

修改UIAlertController的背景和文本颜色是实现一个黑暗的主题快速(和诚实肮脏)的方式。周围有圆角一些轻微的文物,这变得更加明显,颜色较深的背景颜色变。特别是在iPad上,该文物是非常明显的。

正确的解决方案可能会使用自定义的报警控制器。 (有没有发现一个尚未看起来大多喜欢的股票之一。)


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

© www.soinside.com 2019 - 2024. All rights reserved.