ios之UI中自定义cell

自定义cell:frame,autolayout,xib,storyboard,不等高问题

利用frame和autolayout自定义cell

新建一个继承自UITableViewCell的子类,比如LJTgCell

@interface XMGTgCell : UITableViewCell
@end

在LJTgCell.m文件中

  • 重写-initWithStyle:reuseIdentifier:方法
    • 在这个方法中添加所有需要显示的子控件
    • 给子控件做一些初始化设置(设置字体、文字颜色等)
    • 注意:如果是autolayout就要添加子控件的完整约束
/**
 *  在这个方法中添加所有的子控件
 */
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        // ......
    }
    return self;
}
  • 重写-layoutSubviews方法
    • 一定要调用[super layoutSubviews]
    • 在这个方法中计算和设置所有子控件的frame
/**
 *  在这个方法中计算所有子控件的frame
 */
- (void)layoutSubviews
{
    [super layoutSubviews]; // 这句话很容易漏写

    // ......
}

在LJTgCell.h文件中提供一个模型属性,比如LJTg模型

@class LJTg;
@interface LJTgCell : UITableViewCell
/** 团购模型数据 */
@property (nonatomic, strong) LJTg *tg;
@end

在LJTgCell.m中重写模型属性的set方法

  • 在set方法中给子控件设置模型数据
- (void)setTg:(XMGTg *)tg
{
    _tg = tg;

    // .......
}

在控制器中

  • 实现数据源方法
// 有多少组
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
// 每组有多少行
- (NSInteger)tableView:(UITableView *)tableView
  numberOfRowsInSection:(NSInteger)section
// 每行里面的内容
- (UITableViewCell *)tableView:(UITableView *)tableView 
  cellForRowAtIndexPath:(NSIndexPath *)indexPath
  • 注册cell的类型(frame版)
[self.tableView registerClass:[LJTgCell class] forCellReuseIdentifier:ID];
  • 注意:注册cell的类型(xib版)
[self.tableView registerNib:[UINib nibWithNibName:
NSStringFromClass([LJTgCell class]) bundle:nil]forCellReuseIdentifier:ID];
  • 给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 访问缓存池
    XMGTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    // 设置数据(传递模型数据)
    cell.tg = self.tgArray[indexPath.row];

    return cell;
}

利用xib自定义cell

新建一个继承自UITableViewCell的子类,比如LJTgCell

@interface LJTgCell : UITableViewCell
@end

新建一个xib文件(文件名最好跟类名一致,比如LJTgCell.xib)

  • 可以在新建cell类上直接新建对应的xib文件

  • 修改cell的class为LJTgCell

  • 绑定循环利用标识

  • 添加子控件,设置子控件约束

  • 将子控件连线到类扩展中
@interface LJTgCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLabel;
@end

在LJTgCell.h文件中提供一个模型属性,比如LJTg模型

@class LJTg;

@interface LJTgCell : UITableViewCell
/** 团购模型数据 */
@property (nonatomic, strong) LJTg *tg;
@end

在LJTgCell.m中重写模型属性的set方法

  • 在set方法中给子控件设置模型数据
- (void)setTg:(Tg *)tg
{
    _tg = tg;

    // .......
}

在控制器中

  • 注册xib文件(xib版)
[self.tableView registerNib:[UINibnibWithNibName:
NSStringFromClass([LJTgCell class]) bundle:nil] forCellReuseIdentifier:ID];
  • 给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView
  cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 访问缓存池
    LJTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    // 设置数据(传递模型数据)
    cell.tg = self.tgs[indexPath.row];

    return cell;
}

利用stroyboard自定义cell

新建一个继承自UITableViewCell的子类,比如LJTgCell

@interface LJTgCell : UITableViewCell
@end

在storyboard文件中,找到UITableView里面的cell(动态cell)

  • 修改cell的class为LJTgCell

  • 绑定循环利用标识(此时就不用在控制器中注册了)

  • 添加子控件,设置子控件约束

  • 将子控件连线到类扩展中
@interface LJTgCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLabel;
@end

cell不等高的方法(2种)

方法一:直接在控制器设置height的viewDidLoad方法中设置

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 告诉tableView所有cell的真实高度是自动计算(根据设置的约束来计算)
    self.tableView.rowHeight = UITableViewAutomaticDimension;
    // 告诉tableView所有cell的估算高度
    self.tableView.estimatedRowHeight = 44;
}

方法二:给模型增加frame数据

在LJStatus.m中

  • 所有子控件的frame
  • cell的高度
@interface LJStatus : NSObject
/**** 文字\图片数据 ****/
// .....

/**** frame数据 ****/
/** 头像的frame */
@property (nonatomic, assign) CGRect iconFrame;
// .....
/** cell的高度 */
@property (nonatomic, assign) CGFloat cellH;
@end
  • 重写模型cellH属性的get方法
- (CGFloat)cellH
{
    if (_cellH == 0) {
        // ... 计算所有子控件的frame、cell的高度
    }
    return _cellH;
}

在控制器中

  • 实现一个返回cell高度的代理方法
    • 在这个方法中返回indexPath位置对应cell的高度
/**
 *  返回每一行cell的具体高度
 */
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    LJStatus *status = self.statuses[indexPath.row];
    return status.cellH;
}
  • 给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"status";
    // 访问缓存池
    LJStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    // 设置数据(传递模型数据)
    cell.status = self.statuses[indexPath.row];

    return cell;
}

新建一个继承自UITableViewCell的子类,比如LJStatusCell

@interface LJStatusCell : UITableViewCell
@end

在LJStatusCell.m文件中

  • 重写-initWithStyle:reuseIdentifier:方法
    • 在这个方法中添加所有可能显示的子控件
    • 给子控件做一些初始化设置(设置字体、文字颜色等)
/**
 *  在这个方法中添加所有的子控件
 */
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        // ......
    }
    return self;
}

在LJStatusCell.h文件中提供一个模型属性,比如LJStatus模型

@class LJStatus;

@interface LJStatusCell : UITableViewCell
/** 团购模型数据 */
@property (nonatomic, strong) LJStatus *status;
@end

在LJStatusCell.m文件中重写模型属性的set方法

  • 在set方法中给子控件设置模型数据
- (void)setStatus:(LJStatus *)status
{
    _status = status;

    // .......
}

重写-layoutSubviews方法

  • 一定要调用[super layoutSubviews]
  • 在这个方法中设置所有子控件的frame
/**
 *  在这个方法中设置所有子控件的frame
 */
- (void)layoutSubviews
{
    [super layoutSubviews];

    // ......
}
posted @ 2015-11-25 21:02  LongLJ  阅读(312)  评论(0编辑  收藏  举报