自定义View

2018-05-11 13:48:58 浏览数 (1)

自定义View

通过纯代码自定义控件

  • 继承自系统自带的控件,写一个属于自己的控件
  • 在 .h 文件中声明模型对象 @class@property(nonatomic,strong)Shop *shop;
  • 目的:封装控件内部的细节,不让外界关心
  • 步骤
    • 新建一个继承UIView的类
    • 在initWithFrame:方法中添加子控件
      • 当控件第一次创建或者通过 init 和initWithFrame 创建都会调用 initWithFrame方法
      • 但是通过Xib创建且不通过 init 或 initWithFrame 而创建则不会调用 initWithFrame方法
      • 如果控件通过Xib,storyboard 创建,初始化会调用initWithCoder
      • 如果控件通过Xib,storyboard 创建,初始化完毕会调用awakeFromNib建议在此设置必要的Frame
代码语言:javascript复制
-(instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {

        UIImageView *shopImage = [[UIImageView alloc] init];
        [self addSubview:shopImage];
        _shopImage = shopImage;

        UILabel *shopLabel = [[UILabel alloc] init];
        [self addSubview:shopLabel];
        _shopLabel = shopLabel;

    }
    return self;
}
代码语言:javascript复制
- 在layoutSubviews方法中设置子控件的frame
    - 一定要调用[super layoutSubviews];
代码语言:javascript复制
/**
 * 当前控件的frame发生改变的时候就会调用
 * 第一次显示也会调用
 * 这个方法专门用来布局子控件,设置子控件的frame
 */
- (void)layoutSubviews
{
    // 一定要调用super方法
    [super layoutSubviews];

    CGFloat shopW = self.frame.size.width;
    CGFloat shopH = self.frame.size.height;

    self.shopImage.frame = CGRectMake(0, 0, shopW, shopW);
    self.shopLabel.frame = CGRectMake(0, shopW, shopW, shopH - shopW);
}
代码语言:javascript复制
- 提供一个模型属性,重写模型属性的set方法
    - 在set方法中取出模型属性,给对应的子控件赋值
代码语言:javascript复制
//重写set方法
- (void)setShop:(Shop *)shop
{
    _shop = shop;

    self.shopImage.image = [UIImage imageNamed:shop.icon];

    self.shopLabel.text = shop.namelabel;
}

通过xib自定义控件

  • 新建一个继承UIView的类
代码语言:javascript复制
 (instancetype)photoViewWithPhoto:(Photo *)photo
{
    SYLView *sylView = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];

    sylView.photo = photo;

    return sylView;
}
  • 新建一个xib文件(xib的文件名最好跟控件类名一样)
    • 添加子控件、设置子控件属性
    • 修改最外面那个控件的class为控件类名
    • 将子控件进行连线
  • 提供模型属性,重写模型的set方法
    • 在set方法中给子控件设置数据
代码语言:javascript复制
//重写set方法
- (void)setPhoto:(Photo *)photo
{
    _photo = photo;

    _photoShow.image = [UIImage imageNamed:photo.photoName];
    _pledge.text = photo.pledge;
}

加载 xib方法

  • xib 编译之后变为 Nib 文件
  • 第一种加载方法 //返回一个数组 NSArry *xibArray = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil];
  • 第二中加载方法
代码语言:javascript复制
/*
 * 参数 NSString * 是 xib 文件名
 *      NSBundle * 传入 mainBundle
 *          如果传入参数是 mainBundle 则可以传入 nil
 *
 */
UINib *nib = [UINib nibWithNibName:<#(NSString *)#> bundle:<#(NSBundle *)#>]

xib 和 storyboard 对比

共同点

  • 都用来描述软件界面
  • 都用Interface Builder 工具来编辑
  • 本质都是转换成代码去创建控件

不同点

  • xib 是轻量级的,用来描述局部的 UI 界面
  • storyboard 是重量级的,用来描述整个软件的多个界面
  • 并且 storyboard 能展示多个界面之间的跳转关系

0 人点赞