在看一些第三方框架的时候发现了一些使用appearance方法的,于是就研究了一下,觉得还是挺有趣的:
1.关于Appearance:
@protocol UIAppearance <NSObject>
UIAppearance本身是一个协议,在协议中有以下几种方法:
// 初始化方法,支持遵守UIAppearance协议的类,可以直接初始化出对应类,再进行属性修改
+ (instancetype)appearance;
// 在指定类中修改属性,后面跟class,(最后跟一个nil),这行代码以后在指定类中创建的对象就会遵守进行的属性修改,iOS9被下一个方法替换
+ (instancetype)appearanceWhenContainedIn:(nullable Class <UIAppearanceContainer>)ContainerClass, ... NS_REQUIRES_NIL_TERMINATION NS_DEPRECATED_IOS(5_0, 9_0, "Use +appearanceWhenContainedInInstancesOfClasses: instead") __TVOS_PROHIBITED;
// iOS9之后替换上一个方法的,我感觉就是将之前的class,nil变为一个@[class]的数组
+ (instancetype)appearanceWhenContainedInInstancesOfClasses:(NSArray<Class <UIAppearanceContainer>> *)containerTypes NS_AVAILABLE_IOS(9_0);
// 在指定状态下修改指定对象属性,比如将在横屏状态和竖屏状态下显示不同颜色
+ (instancetype)appearanceForTraitCollection:(UITraitCollection *)trait NS_AVAILABLE_IOS(8_0);
+ (instancetype)appearanceForTraitCollection:(UITraitCollection *)trait whenContainedIn:(nullable Class <UIAppearanceContainer>)ContainerClass, ... NS_REQUIRES_NIL_TERMINATION NS_DEPRECATED_IOS(8_0, 9_0, "Use+appearanceForTraitCollection:whenContainedInInstancesOfClasses: instead") __TVOS_PROHIBITED;
+ (instancetype)appearanceForTraitCollection:(UITraitCollection *)trait whenContainedInInstancesOfClasses:(NSArray<Class <UIAppearanceContainer>> *)containerTypes NS_AVAILABLE_IOS(9_0);
2. 支持UIAppearance类
** 1.UIActivitiIndicatorView**
** 2.UIBarButtonItem**
** 3.UIBarItem**
** 4.UINavgationBar**
** 5.UIPopoverControll**
** 6.UIProgressView**
** 7.UISearchBar**
** 8.UISegmentControll **
** 9.UISlider**
** 10.UISwitch**
** 11.UITabBar**
** 12.UITabBarItem**
** 13.UIToolBar**
** 14.UIView**
** 15.UIViewController**
3. 例子
- (void)viewDidLoad {
[super viewDidLoad];
blueView *bView = [[blueView alloc] init];
redView *rView = [[redView alloc] init];
[self.view addSubview:bView];
[self.view addSubview:rView];
// btn1在设置UIAppearance前添加到bView
UIButton *btn1 = [[UIButton alloc] init];
btn1.frame = CGRectMake(100, 100, 50, 50);
btn1.backgroundColor = [UIColor blackColor];
[bView addSubview:btn1];
// btn2在设置UIAppearance前添加到rView
UIButton *btn2 = [[UIButton alloc] init];
btn2.frame = CGRectMake(100, 100, 50, 50);
btn2.backgroundColor = [UIColor blackColor];
[rView addSubview:btn2];
// btn3在设置UIAppearance后添加到bView
UIButton *btn3 = [[UIButton alloc] init];
btn3.frame = CGRectMake(100, 200, 50, 50);
btn3.backgroundColor = [UIColor blackColor];
// btn4在设置UIAppearance后添加到rView
UIButton *btn4 = [[UIButton alloc] init];
btn4.frame = CGRectMake(100, 200, 50, 50);
btn4.backgroundColor = [UIColor blackColor];
// btn5在设置UIAppearance后添加到rView
UIButton *btn5 = [[UIButton alloc] init];
btn5.frame = CGRectMake(100, 300, 50, 50);
btn5.backgroundColor = [UIColor blackColor];
[rView addSubview:btn2];
//设置UIAppearance
[[UIButton appearanceWhenContainedInInstancesOfClasses:@[[redView class]]] setBackgroundColor:[UIColor greenColor]];
// 设置UIAppearance后修改btn4的颜色
btn4.backgroundColor = [UIColor blackColor];
[bView addSubview:btn3];
[rView addSubview:btn4];
[rView addSubview:btn5];
}
如图:
1. 由btn1与btn2对比可知:指定了redView类型的Appearance对redView上的btn产生影响;
2. 由btn1与btn3对比可知:指定了redView类型的Appearance并未对
3. blueView上的btn产生影响;
4. 由btn2与btn4对比可知:在指定Appearance之前修改属性不会生效,在指定Appearance之后修改对象属性,会生效;
5. 由btn2与btn5对比可知:指定Appearance前后添加到View上不会影响Appearance的效果;
4. 使用场景:
- 一次性指定默写控件的特性比如自定义tabBarVC的UIBarButtonItem和UIBarItem等;
- 一件换肤:根据拼接的图片或者文件名,批量刷新UI的图片等(通过拼接将red_backImage变成blue_backImage);
具体的代码有时间写完再更新谢谢
5. 参考博客,十分感谢作者:
- iOS UIAppearance使用详解:
http://blog.sina.com.cn/s/blog_9693f61a0101f1rs.html - iOS --思考appearance主题:
http://www.jianshu.com/p/8262ec74bfc7 - iOS --统一UINavigationBar的主题appearance:
http://www.jianshu.com/p/73bfbc7210a7 - WWDC 2014 Session笔记 - iOS界面开发的大一统
https://onevcat.com/2014/07/ios-ui-unique/ - iOS --统一UINavigationBar的主题appearance