IOS开发 - 04.自定义视图

1.自定义视图的目的

  • 通常在开发APP时,系统自带的视图控件不能满足我们的要求,或者需要经常使用模块的视图控件,这里我们可以将该模块封装,封装后的视图就是自定义视图
  • 目的:
    • 提高代码的复用性
    • 屏蔽内部的实现细节

2.如何创建一个自定义视图

这里写图片描述

  • 这里的每一个红色模块都是一个自定义视图

  • 1.自定义一个类继承于UIView

    • UIView中声明模型属性,方便根据传入的值设置控件的数据
#import <UIKit/UIKit.h>

@class ZJShop;
@interface NJShopView : UIView
// 数据模型
@property(nonatomic, strong)ZJShop *shop;
@end
  • 2.在initWithFrame方法中添加子控件
    • 注意: 如果自定义一个View,不建议在init方法中设置子控件的位置
    • 因为如果子控件的位置需要根据父控件的frame来计算, 在init方法中拿不到父控件的frame
    • 注意:在调用init和initWithFrame:时,都会调用initWithFrame:方法,而调用initWithFrame:不会调用init方法,所以这里建议在重写init方法时,重写父类的initWithFrame:方法
    • 这样我们不论是通过alloc init和alloc initWithFrame:的时候,都能正常进行初始化
    • -
#import "ZJShopView.h"
#import "ZJShop.h"
@interface ZJShopView ()
// 定义子控件视图
// 内部控件属性一般定义在匿名分类中
@property (nonatomic, weak) UIImageView *iv;
@property (nonatomic, weak) UILabel *introLabel;

@end

@implementation ZJShopView
-(nonnull instancetype)initWithFrame:(CGRect)frame{

    if (self = [super initWithFrame:frame]) {

        // 创建头像控件
        UIImageView *imgView = [[UIImageView alloc] init];
        [self addSubview:imgView];
        self.iv = imgView;

        // 创建label控件
        UILabel *contentLabel = [[UILabel alloc] init];
        contentLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:contentLabel];
        self.introLabel = contentLabel;

    }
    return self;
}


@end
  • 3.在layoutSubviews中设置子控件的位置
    • layoutSubviews方法是专门用于布局子控件的位置的
    • 注意: 重写layoutSubviews方法, 一定要调用[super layoutSubviews]方法,如果不调用, 会出现一些奇葩的错误
    • layoutSubviews方法什么时候调用
      • 1.只要创建一个控件, 那么就会调用
      • 2.只要修改控件的尺寸就会调用(bounds/frame)
      • 3.修改位置不会调用
      • 4.如果当前修改的尺寸和上一次的尺寸没有变化, 不会调用
   /**
 *  重写layoutSubviews,设置子控件的位置尺寸
 */
-(void)layoutSubviews{
    [super layoutSubviews];
    self.iv.frame = CGRectMake(0, 0, kShopViewW, kShopViewW);
    self.introLabel.frame = CGRectMake(0, kShopViewW, kShopViewW, kShopViewH - kShopViewW);
}
  • 4.提供一个属性保存外界传入的数据(模型对象),重写setter方法设置子控件的数据
/**
 *  重写setter方法,设置控件数据
 */
-(void)setShop:(ZJShop *)shop{
    _shop = shop;
    // 设置子控件的数据
    self.iv.image = [UIImage imageNamed:shop.icon];
    self.introLabel.text = shop.intro;
}   

3.类工厂方法(便利构造器)

  • 按照苹果的风格和规范,一般情况一个用于创建对象的对象方法会对应一个类方法
  • 可以通过类工厂方法, 快速的根据数据创建一个对象
  • 注意点:
    • 返回值一定要使用instancetype, 不要使用id
    • 在类工厂方法中创建对象, 使用self, 不要使用类名
//快速构造方法
-(instancetype)initWithShop:(ZJShop *)shop;
+(instancetype)shopViewWith:(ZJShop *)shop;
// 实现
-(instancetype)initWithShop:(ZJShop *)shop{
    if (self = [super init]) {
        self.shop = shop;
    }
    return self;
}
+(instancetype)shopViewWith:(ZJShop *)shop{
    return [[self alloc] initWithShop:shop];
}

4.layoutSubViews方法

  • 作用:

    • 布局子控件,用于调整子控件的位置
  • 调用时间:

    • 控件第一次被创建
    • 控件的尺寸被修改时
  • 注意点:

    • 重写layoutSubViews方法时,一定要调用父类的方法[super layoutSubViews];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值