您的位置:首页 > 产品设计 > UI/UE

谈谈改变 UIAlertView 和 UIActionSheet 的颜色 iOS8及以上应该使用的方式

2017-05-25 10:04 537 查看
对于>=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 ViewsYou 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有讨论
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: