UIAppearance

1,系统控件的使用及注意实现

注意:
1,+appearance 在设置之后的控件才起作用,这就是为什么在控制器中通过appearance修改了导航栏的属性,而该导航栏的实例属性没有改变的原因(这种情况应该通过实例获取,并修改属性),但是如果下一个导航栏生效后,原来的导航栏也会全局改变,例如,在A页面中appearance全局修改导航栏为蓝色,那么A push到B,导航栏没有从新生成,原来的导航栏还是默认颜色不会变成蓝色,但是如果A present一个带有导航栏的控制器C,那么C的导航栏会变成蓝色,dismiss到A,A的导航栏也会变成蓝色(是不是很意外)。
2,只有标记UI_APPEARANCE_SELECTOR(OC)或 swift中是在方法或属性前面添加dynamic才会生效。
3,appearanceWhenContainedIn:接收可选参数,实现设置某些类中才有效的全局属性。
参考:http://www.cocoachina.com/ios/20150723/12671.html

2,自定义控件实现UIAppearance

比如自定义的一个弹框控件,在a app中显示的确定取消按钮是红色,在b app中显示的是绿色,这个全局的控制可以通过一个静态变量保存属性来设置,也可以通过UIAppearance来实现:

// RoundLabel.h

@interface RoundLabel : UILabel

@property (nonatomic, assign) CGFloat borderWidth UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign) CGFloat cornerRadius UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign) UIColor *borderColor UI_APPEARANCE_SELECTOR;

@end

@implementation RoundLabel

- (void)drawRect:(CGRect)rect {

    [super drawRect:rect];

    self.layer.borderColor = _borderColor.CGColor;
    self.layer.cornerRadius = _cornerRadius;
    self.layer.borderWidth = _borderWidth;
}

- (void)setBorderWidth:(CGFloat)borderWidth {
    _borderWidth = borderWidth;
}

- (void)setCornerRadius:(CGFloat)cornerRadius {
    _cornerRadius = cornerRadius;
}

- (void)setRectColor:(UIColor *)rectColor {
    _borderColor = rectColor;
}
@end

但这里有个疑问,RoundLabel的
+ (void)initialize {
[[self appearance] setCornerRadius:5];
[[self appearance] setBorderWidth:2];
[[self appearance] setBorderColor:[UIColor cyanColor]];
}
方法中默认设置了属性,在控制器中初始化label1然后再通过appearance修改全局属性,再添加label2(不单独设置实例属性)结果是label1和label2的borderWidth等属性是一样。我猜测是上面的控件label1在添加后其实还没有真正渲染,拿取属性是在渲染的时候获取的。

你可能感兴趣的:(UIAppearance)