15 View的封装

View封装(自定义)

  1. 如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心

  2. 外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据

  3. 封装控件的基本步骤

    在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

 

 

补充封装的步骤

  1. init或者initwithframe方法用来 -- 创建控件

  2. layoutsubviews方法用来 -- 设置frame 【注意这个方法调用的时刻】

  3. 用模型的set方法 -- 设置数据

注意:如果用initwithframe方法,frame传进来了,最后也不要在初始化的时候设置子控件的frame,可能frame是nil空,最好在layoutsubviews方法中设置frame,控件的frame以改变就会调用这个方法。

补充init方法和initwithframe方法关系:

init方法调用后内部会默认调用initwithframe方法,所以从封装的角度来说,无论外边是调用那个都会调用initwithframe方法,这样的话,别人调用的时候才不会出错,因为他不知道你写的是哪个方法
  1. 为什么set方法就能赋值显示:是不是控件显示之间都可以重新赋值

  2. 便利构造方法:就是类型方法 代码示例如上

  3. 懒加载的好处:用到的时候再去创建, 如当用户操作到某个功能的时候再去显示一个控件

     

posted @ 2016-09-11 08:27  <瑾瑜>  阅读(113)  评论(0)    收藏  举报