通过Category让UIView更方便的布局

之前我们给一个控件设置宽高或者位置的时候会用下面代码:

    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方法么?

  1. category中的属性不能自动生成实例变量(类似:_xxx),所以我们有时会看到通过runtime的方式将变量绑定到实例上。
  2. 上面例子,定义属性为了生成setter跟getter方法。没有用到任何有关self.xself.yself.width或者_x_y这些自定义属性,都是通过UIView自带属性frame(self.frame)来实现给UIView设置布局,所以不需要用runtime。所以本例子不定义属性也可以,把属性注释掉,然后将下面方法取消注释,一样能用。

--EOF--