15 View的封装
View封装(自定义)
-
如果一个view内部的子控件比较多,一般会考虑自定义一个view,
把它内部子控件的创建屏蔽起来,不让外界关心 -
外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据
-
封装控件的基本步骤
在initWithFrame:方法中添加子控件,提供便利构造方法在layoutSubviews方法中设置子控件的frame(一定要调用super的layoutSubviews)增加模型属性,在模型属性set方法中设置数据到子控件上
代码示例:
//在.h中用这个声明 效率高 @class XMGShop; @interface XMGShopView : UIView /** 商品模型 */ @property (nonatomic, strong) XMGShop *shop; //便利构造函数 + (instancetype)shopView; @end
#import "ZZFShopView.h" #import "ZZFShop.h" @interface ZZFShopView() /** 图片控件 */ @property (nonatomic, strong) UIImageView *iconView; /** 名字控件 */ @property (nonatomic, strong) UILabel *nameLabel; @end @implementation ZZFShopView //便利构造函数 + (instancetype)shopView { return [[self alloc] init]; } //懒加载 用到的时候再去加载,这是一种方法 - (UIImageView *)iconView { if (_iconView == nil) { UIImageView *iconView = [[UIImageView alloc] init]; iconView.backgroundColor = [UIColor blueColor]; [self addSubview:iconView]; _iconView = iconView; } return _iconView; } - (UILabel *)nameLabel { if (_nameLabel == nil) { UILabel *nameLabel = [[UILabel alloc] init]; nameLabel.font = [UIFont systemFontOfSize:11]; nameLabel.textAlignment = NSTextAlignmentCenter; nameLabel.backgroundColor = [UIColor redColor]; [self addSubview:nameLabel]; _nameLabel = nameLabel; } return _nameLabel; } /** 步骤1 init方法内部会自动调用initWithFrame:方法 */ - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor orangeColor]; // 添加图片 // UIImageView *iconView = [[UIImageView alloc] init]; // iconView.backgroundColor = [UIColor blueColor]; // [self addSubview:iconView]; // self.iconView = iconView; // 添加文字 // UILabel *nameLabel = [[UILabel alloc] init]; // nameLabel.font = [UIFont systemFontOfSize:11]; // nameLabel.textAlignment = NSTextAlignmentCenter; // nameLabel.backgroundColor = [UIColor redColor]; // [self addSubview:nameLabel]; // self.nameLabel = nameLabel; } return self; } /** * 这个方法专门用来布局子控件,一般在这里设置子控件的frame * 当控件本身的尺寸发生改变的时候,系统会自动调用这个方法 * 步骤2 */ - (void)layoutSubviews{ // 一定要调用super的layoutSubviews [super layoutSubviews]; CGFloat shopW = self.frame.size.width; CGFloat shopH = self.frame.size.height; self.iconView.frame = CGRectMake(0, 0, shopW, shopW); self.nameLabel.frame = CGRectMake(0, shopW, shopW, shopH - shopW); } //步骤3 - (void)setShop:(XMGShop *)shop { _shop = shop; self.nameLabel.text = shop.name; self.iconView.image = [UIImage imageNamed:shop.icon]; } @end
补充封装的步骤
-
init或者initwithframe方法用来 -- 创建控件
-
layoutsubviews方法用来 -- 设置frame 【注意这个方法调用的时刻】
-
用模型的set方法 -- 设置数据
注意:如果用initwithframe方法,frame传进来了,最后也不要在初始化的时候设置子控件的frame,可能frame是nil空,最好在layoutsubviews方法中设置frame,控件的frame以改变就会调用这个方法。
补充init方法和initwithframe方法关系:
init方法调用后内部会默认调用initwithframe方法,所以从封装的角度来说,无论外边是调用那个都会调用initwithframe方法,这样的话,别人调用的时候才不会出错,因为他不知道你写的是哪个方法
-
为什么set方法就能赋值显示:是不是控件显示之间都可以重新赋值
-
便利构造方法:就是类型方法 代码示例如上
-
懒加载的好处:用到的时候再去创建, 如当用户操作到某个功能的时候再去显示一个控件

浙公网安备 33010602011771号