之前我们给一个控件设置宽高或者位置的时候会用下面代码:
UIView *view = [UIView new];
CGRect frame = view.frame;
frame.size.width = 100;
view.frame = frame;
上面方式很麻烦,不解释。下面是对UIView的分类,方便了对控件的布局:
UIView+Category.h文件
#import <UIKit/UIKit.h>
@interface UIView (Extension)
@property (nonatomic,assign) CGFloat x;
@property (nonatomic,assign) CGFloat y;
@property (nonatomic,assign) CGFloat width;
@property (nonatomic,assign) CGFloat height;
@property (nonatomic,assign) CGSize size;
@property (nonatomic,assign) CGPoint origin;
//- (void)setX:(CGFloat)x;
//- (CGFloat)x;
//- (void)setY:(CGFloat)y;
//- (CGFloat)y;
//- (void)setWidth:(CGFloat)width;
//- (CGFloat)width;
//- (void)setHeight:(CGFloat)height;
//- (CGFloat)height;
//- (void)setOrigin:(CGPoint)origin;
//- (CGPoint)origin;
//- (void)setSize:(CGSize)size;
//- (CGSize)size;
@end
UIView+Category.m文件
#import "UIView+Category.h"
@implementation UIView (Extension)
- (void)setX:(CGFloat)x {
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
- (CGFloat)x {
return self.frame.origin.x;
}
- (void)setY:(CGFloat)y {
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
self.frame = frame;
}
- (CGFloat)y {
return self.frame.origin.y;
}
- (void)setWidth:(CGFloat)width {
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
- (CGFloat)width {
return self.frame.size.width;
}
- (void)setHeight:(CGFloat)height {
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
- (CGFloat)height {
return self.frame.size.height;
}
- (void)setOrigin:(CGPoint)origin {
CGRect frame = self.frame;
frame.origin = origin;
self.frame = frame;
}
- (CGPoint)origin {
return self.frame.origin;
}
- (void)setSize:(CGSize)size {
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}
- (CGSize)size {
return self.frame.size;
}
@end
现在就可以通过下面方式对UIView进行布局了:
UIView *view = [UIView new];
view.width = 100;
view.height = 100;
view.x = 100;
view.y = 100;
//或者
view.origin = CGPointMake(100, 100);
view.size = CGSizeMake(100, 100);
最后你可能有疑问,category中不是不能定义属性么?即使可以定义属性,不应该用runtime来实现setter跟getter方法么?
- category中的属性不能自动生成实例变量(类似:_xxx),所以我们有时会看到通过runtime的方式将变量绑定到实例上。
- 上面例子,定义属性为了生成setter跟getter方法。没有用到任何有关
self.x
、self.y
、self.width
或者_x
、_y
这些自定义属性,都是通过UIView自带属性frame(self.frame)来实现给UIView设置布局,所以不需要用runtime。所以本例子不定义属性也可以,把属性注释掉,然后将下面方法取消注释,一样能用。
–EOF–