谈谈改变 UIAlertView 和 UIActionSheet 的颜色

Posted yohunl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谈谈改变 UIAlertView 和 UIActionSheet 的颜色相关的知识,希望对你有一定的参考价值。

ios8及以上应该使用的方式

对于>=iOS8来说, UIAlertView,UIActionSheet都被 UIAlertController替代了,
建立一个 UIAlertView的方式

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title"
                                                                                 message:@"Message"
                                                                          preferredStyle:UIAlertControllerStyleAlert];
建立一个UIActionSheet
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title"
                                                                                 message:@"Message"
                                                                          preferredStyle:UIAlertControllerStyleActionSheet];

改变 UIAlertController 颜色的方式

        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title"
                                                                                 message:@"Message"
                                                                          preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancelButton = [UIAlertAction actionWithTitle:@"Cancel"
                                                               style:UIAlertActionStyleCancel
                                                             handler:nil];
        UIAlertAction *destructiveButton = [UIAlertAction actionWithTitle:@"Destructive"
                                                                    style:UIAlertActionStyleDestructive
                                                                  handler:nil];
        UIAlertAction *otherButton1 = [UIAlertAction actionWithTitle:@"Button 1"
                                                               style:UIAlertActionStyleDefault
                                                             handler:nil];
        UIAlertAction *otherButton2 = [UIAlertAction actionWithTitle:@"Button 2"
                                                               style:UIAlertActionStyleDefault
                                                             handler:nil];
        [alertController addAction:cancelButton];
        [alertController addAction:destructiveButton];
        [alertController addAction:otherButton1];
        [alertController addAction:otherButton2];
        alertController.view.tintColor = [UIColor colorWithRed:0.7596 green:0.5249 blue:1.0 alpha:1.0];//这句就可以了! 当然了,如果你没设置这一句,
        [self presentViewController:alertController animated:YES completion:nil];


总结出来的可以用来改变颜色的方式

方法1:
修改alertController.view.tintColor的tintColor

alertController.view.tintColor = [UIColor colorWithRed:0.7596 green:0.5249 blue:1.0 alpha:1.0];

但是,实际上,在测试的时候,发现,这种修改后,手指在选项上滑动后,颜色就又变为默认的蓝色了…….,具体可以看下面的gif动画演示

另外
stackoverflow上很多说是在AppDelegate中添加

[[UIView appearanceWhenContainedInInstancesOfClasses:@[[UIAlertController class]]] setTintColor:[UIColor redColor]];

可以让所有的UIAlertController的颜色都改变,但是,但是,经过我测试,添加这句根本没有效果,不仅没有效果,添加了这句后,这样的设置alertController.view.tintColor = [UIColor colorWithRed:0.7596 green:0.5249 blue:1.0 alpha:1.0];将不再有效,系统弹出的是默认的颜色了!!!!
至于为什么会这样,我也没有得到一个可以让自己信服的理由!

方法2:
修改window的tintColor,这种方式不会有方式一的问题

[UIApplication sharedApplication].keyWindow.tintColor = [UIColor yellowColor];

至于这句在什么地方加,当然是随你心情了,只要在其显示之前添加,都是OK的

方法3:
私有API(注意这种方式不能上appstore的,会因为调用私有api被苹果拒的)
iOS-Runtime-Headers中UIAlertAction头文件我们可以看到
UIAlertAction 有一个私有api

- (void)_setTitleTextColor:(id)arg1;

从名字就可以看出,这个是改变文字颜色的

在代码中

        UIAlertAction *otherButton1 = [UIAlertAction actionWithTitle:@"Button 1"
                                                               style:UIAlertActionStyleDefault
                                                             handler:nil];
        [otherButton1 performSelector:@selector(_setTitleTextColor:) withObject:[UIColor yellowColor]];

就可以实现了!

方法4 :
使用KVC

  [otherButton1 setValue:[UIColor yellowColor] forKey:@"titleTextColor"];
  //[otherButton1 setValue:[UIColor yellowColor] forKey:@"_titleTextColor"];

这种方式,是合法的方式调用私有方法或者属性,这个是KVC的特性决定的

使用以前的UIAlertView的怎么改变呢?

网上的第一种方式

使用Appearance的方式
ios9之前

  [[UIView appearanceWhenContainedIn:[UIAlertView class], nil] setTintColor:[UIColor redColor]];
  [[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor redColor]];

ios9之后

    [[UIView appearanceWhenContainedInInstancesOfClasses:@[[UIAlertView class]]] setTintColor:[UIColor redColor]];
    [[UIView appearanceWhenContainedInInstancesOfClasses:@[[UIAlertController class]]] setTintColor:[UIColor redColor]];

经过测试,是起不到任何作用的,因为苹果官方上说到了
Appearance of Alert Views
You cannot customize the appearance of alert views.

网上的第二种方式:重载UIAlertView

可以参考[how-to-change-color-of-the-uialertview-dialog-in-ios](
http://stackoverflow.com/questions/9940145/how-to-change-color-of-the-uialertview-dialog-in-ios)

但是这个有一个问题,UIAlertView内部的实现,在不同版本是不一样的,所以即使在一个sdk上可以了,其它的也不一定可以,尤其是在iOS9中,
我们从iOS-Runtime-Headers查看UIAlertView的头文件

@interface UIAlertView : UIView 
    BOOL __currentlyRunningModal;
    NSMutableArray *_actions;
    UIAlertController *_alertController;
    BOOL _alertControllerShouldDismiss;
    int _alertViewStyle;
    int _cancelIndex;
    id _context;
    int _defaultButtonIndex;
    id _delegate;
    BOOL _dismissingAlertController;
    UIViewController *_externalViewControllerForPresentation;
    int _firstOtherButtonIndex;
    BOOL _handlingAlertActionShouldDismiss;
    BOOL _hasPreparedAlertActions;
    BOOL _isPresented;
    NSString *_message;
    _UIAlertControllerShimPresenter *_presenter;
    UIAlertView *_retainedSelf;
    BOOL _runsModal;
    NSString *_subtitle;

可以看到,其内部实现可能已经换为 VIewController的形式来实现了!!

所以这种方式也不行的!!

网上的第三种方式

[how-to-change-uialertview-text-color](
http://stackoverflow.com/questions/4755313/how-to-change-uialertview-text-color),枚举UIAlertView的子视图,然后更改

-(void)willPresentAlertView:(UIAlertView *)alertView

    UILabel *titleLabel = [alertView valueForKey:@"_titleLabel"];
    titleLabel.font = [UIFont fontWithName:@"Arial" size:18];
    [titleLabel setTextColor:[UIColor whiteColor]];

     UILabel *body = [alertView valueForKey:@"_bodyTextLabel"];
     body.font = [UIFont fontWithName:@"Arial" size:15];
     [body setTextColor:[UIColor whiteColor]];

但是,这个是不行的!!!在iOS9中,内部实现已经改变,根本没有_titleLabel ,如果你这样写,直接就crash了

那么,难道没有方法改变UIAlertView的颜色了么???
有啊,完全的使用自定义的AlertView.

第四种方式,也是唯一可行的方式

完全使用自定义的AlertView,这样,什么颜色更改呀,字体更改呀,都没有问题了!!
可以参考
https://github.com/Friend-LGA/LGAlertView

https://github.com/szk-atmosphere/MSAlertController

UIActionSheet的颜色改变

同上述的UIAlertView的方式!

参考
uialertcontroller-custom-font-size-color有讨论

以上是关于谈谈改变 UIAlertView 和 UIActionSheet 的颜色的主要内容,如果未能解决你的问题,请参考以下文章

辅助功能:更新 UIAlertView 消息时,Voiceover 读取的文本不会改变?

在 UILabel 上使用外观代理会使我的应用程序被拒绝,因为它会改变 UIAlertView?

UIAlertView,如何在里面放置很多按钮?

更改 UIAlertView 的字体颜色

20.谈谈对mvc的认识。

提示框的使用UIAlertController(UIAlertView和UIActionSheet二合一,包含通知中心的使用)