1 给UIView添加一个非正式协议,(因为普通控件都是集成自UIVIew,所以继承自UIView的控件就都可以使用了)
2.h文件中声明四个属性,分别是:X轴坐标、Y轴坐标、Width和Height
#import <UIKit/UIKit.h>
@interface UIView (JSFrame)
@property (nonatomic,assign) CGFloat x;
@property (nonatomic,assign) CGFloat y;
@property (nonatomic,assign) CGFloat w;
@property (nonatomic,assign) CGFloat h;
@end
3 .m中实现下Setter和Getter方法
- (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;
}
- (CGFloat)y{
return self.frame.origin.y;
}
- (void)setW:(CGFloat)w{
CGRect frame = self.frame;
frame.size.width = w;
self.frame = frame;
}
- (CGFloat)w{
return self.frame.size.width;
}
- (void)setH:(CGFloat)h{
CGRect frame = self.frame;
frame.size.height = h;
self.frame = frame;
}
- (CGFloat)h{
return self.frame.size.height;
}
4.使用:在需要使用的地方导入分类的头文件,创建出来的控件就可以通过点语法的方式直接设置frame了
补充:
除了扩展之外,其他类别都无法向类中新增实例变量,所以,编译器无法把实现属性所需的实例变量合成出来。
从概念上讲,属性是封装数据的方式。类别是扩展类功能的手段,而非封装数据。因此,一般情况下应该避免把属性声明在类别中,而应该声明在“主接口”中
关联对象辅助实现分类添加属性:
#import <UIKit/UIKit.h>
@interface UIImageView (MyView)
//{
// int a;
//}
//属性
@property (nonatomic, copy) NSString *name;
@end
#import "UIImageView+MyView.h"
#import <objc/runtime.h>
/*
1:可以获取对象的所有属性
2:可以动态的给对象添加属性
3:交互系统的方法(换肤)
*/
@implementation UIImageView (MyView)
-(NSString *)name
{
/*
参数1:代表对象本身
参数2:key
*/
return objc_getAssociatedObject(self, @"itcast");
}
-(void)setName:(NSString *)name
{
/*
参数1:代表对象本身
参数2:key
参数3:属性
参数4:属性的修饰符
*/
objc_setAssociatedObject(self, @"itcast", name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end
设置方法中的内存管理语义:
关联类型 等效的@property属性
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC nonatomic, retain
OBJC_ASSOCIATION_COPY_NONATOMIC nonatomic, copy
OBJC_ASSOCIATION_RETAIN retain
OBJC_ASSOCIATION_COPY copy