UI 一一 自定义不等高cell (storyboard方式)

来源:互联网 发布:深圳数据恢复哪家强 编辑:程序博客网 时间:2024/05/16 04:59

通过storyboard方式来自定义不等高cell


  • 添加子控件和contentView之间的间距约束


  • 设置tableViewCell的真实行高和估算行高
// 告诉tableView所有cell的真实高度是自动计算(根据设置的约束来计算)self.tableView.rowHeight = UITableViewAutomaticDimension;// 告诉tableView所有cell的估算高度self.tableView.estimatedRowHeight = 44;


这种self-sizing技术,只支持从iOS8以后版本.

代码如下:

ZYStatus文件

#import <UIKit/UIKit.h>// 模型数据@interface ZYStatus : NSObject/** 图像 */@property (nonatomic, copy) NSString *icon;/** 昵称 */@property (nonatomic, copy) NSString *name;/** 正文(内容) */@property (nonatomic, copy) NSString *text;/** VIP */@property (nonatomic, assign, getter=isVip) BOOL vip;/** 配图 */@property (nonatomic, copy) NSString *picture;@end@implementation ZYStatus@end


ZYStatusCell文件

#import <UIKit/UIKit.h>@class  ZYStatus;@interface ZYStatusCell : UITableViewCell/** 微博模型数据 */@property(nonatomic,strong)ZYStatus *status;@end#import "ZYStatus.h"@interface ZYStatusCell ()/** 图像 */@property (nonatomic, weak)IBOutlet UIImageView *iconImageView;/** 昵称 */@property (nonatomic, weak)IBOutlet UILabel *nameLabel;/** vip */@property (nonatomic, weak)IBOutlet UIImageView *vipImageView;/** 正文 */@property (nonatomic, weak)IBOutlet UILabel *text_Label;/** 配图 */@property (nonatomic, weak)IBOutlet UIImageView *pictureImageView;/** 图片的高度约束 */@property (weak, nonatomic) IBOutlet NSLayoutConstraint *pictureHeight;/** 图片与cell底部的间距约束 */@property (weak, nonatomic) IBOutlet NSLayoutConstraint *pictureBottomSpace;@end@implementation ZYStatusCell////3. 给子控件赋值- (void)setStatus:(ZYStatus *)status{    _status = status;    // 赋值    self.iconImageView.image = [UIImage imageNamed:status.icon];    self.nameLabel.text = status.name;        if (status.isVip) {        self.vipImageView.hidden = NO;        // 有if就有else,如果在这里写字体颜色,会出现数据紊乱,不是会员的用户的名称也是黄色        self.nameLabel.textColor = [UIColor orangeColor];        self.vipImageView.image = [UIImage imageNamed:@"vip"];    }else{        self.vipImageView.hidden = YES;        self.nameLabel.textColor = [UIColor blackColor];    }        self.text_Label.text = status.text;        if (status.picture) {        self.pictureImageView.hidden = NO;        self.pictureImageView.image = [UIImage imageNamed:status.picture];        // 因为有配图的cell,要设置配图的高度        self.pictureHeight.constant = 100;        self.pictureBottomSpace.constant = 10;    }else{        self.pictureImageView.hidden = YES;        // 如果没有配图的cell,要把配图高度约束设为0        self.pictureHeight.constant = 0;        self.pictureBottomSpace.constant = 0;            }    }@end


Main.storyboard文件




ViewController文件

#import "ViewController.h"#import "MJExtension.h"#import "ZYStatusCell.h"#import "ZYStatus.h"@interface ViewController ()/** 所有的微博 */@property (nonatomic,strong) NSArray *statuses;@end@implementation ViewController- (NSArray *)statuses{    if (_statuses == nil) {        //加载plist中的数据到,模型ZYStatus中        _statuses = [ZYStatus mj_objectArrayWithFilename:@"statuses.plist"];    }        return _statuses;}- (void)viewDidLoad {    [super viewDidLoad];        // self-sizing技术,只适合ios8以上版本    // 告诉tableView所有cell的真实高度是自动计算的(根据设置的约束来计算)    self.tableView.rowHeight = UITableViewAutomaticDimension;        // 告诉tableView所有cell的估算高度    self.tableView.estimatedRowHeight = 44;    }#pragma -mark 数据源方法- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return self.statuses.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *ID = @"status";        // 到缓存池中查看是否有可循环利用的cell    ZYStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];        // 传递模型数据    cell.status = self.statuses[indexPath.row];        return cell;}@end




如果要支持iOS8之前

  • 如果cell内部有自动换行的label,需要设置preferredMaxLayoutWidth属性
- (void)awakeFromNib{    // 手动设置文字的最大宽度(目的是:让label知道自己文字的最大宽度,进而能够计算出自己的frame)    self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;}

  • 设置tableView的cell估算高度
// 告诉tableView所有cell的估算高度(设置了估算高度,就可以减少tableView:heightForRowAtIndexPath:方法的调用次数)self.tableView.estimatedRowHeight = 200;

  • 在代理方法中计算cell的高度
ZYStatusCell *cell;- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    // 创建一个临时的cell(cell的作用:根据模型数据布局所有的子控件,进而计算出cell的高度)    if (!cell) {        cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    // 设置模型数据    cell.status = self.statuses[indexPath.row];    return cell.height;}

具体代码如下:

注意: 首先要取消storyboard中与contentView底部的间距


ZYStatus文件

// 模型数据@interface ZYStatus : NSObject/** 图像 */@property (nonatomic, copy) NSString *icon;/** 昵称 */@property (nonatomic, copy) NSString *name;/** 正文(内容) */@property (nonatomic, copy) NSString *text;/** VIP */@property (nonatomic, assign, getter=isVip) BOOL vip;/** 配图 */@property (nonatomic, copy) NSString *picture;@end@implementation ZYStatus@end

ZYStatusCell文件

#import <UIKit/UIKit.h>@class  ZYStatus;@interface ZYStatusCell : UITableViewCell/** 微博模型数据 */@property(nonatomic,strong)ZYStatus *status;- (CGFloat)cellHeight;@end#import "ZYStatus.h"@interface ZYStatusCell ()/** 图像 */@property (nonatomic, weak)IBOutlet UIImageView *iconImageView;/** 昵称 */@property (nonatomic, weak)IBOutlet UILabel *nameLabel;/** vip */@property (nonatomic, weak)IBOutlet UIImageView *vipImageView;/** 正文 */@property (nonatomic, weak)IBOutlet UILabel *text_Label;/** 配图 */@property (nonatomic, weak)IBOutlet UIImageView *pictureImageView;@end@implementation ZYStatusCell////3. 给子控件赋值- (void)setStatus:(ZYStatus *)status{    _status = status;    // 赋值    self.iconImageView.image = [UIImage imageNamed:status.icon];    self.nameLabel.text = status.name;        if (status.isVip) {        self.vipImageView.hidden = NO;        // 有if就有else,如果在这里写字体颜色,会出现数据紊乱,不是会员的用户的名称也是黄色        self.nameLabel.textColor = [UIColor orangeColor];        self.vipImageView.image = [UIImage imageNamed:@"vip"];    }else{        self.vipImageView.hidden = YES;        self.nameLabel.textColor = [UIColor blackColor];    }        self.text_Label.text = status.text;        if (status.picture) {        self.pictureImageView.hidden = NO;        self.pictureImageView.image = [UIImage imageNamed:status.picture];    }else{        self.pictureImageView.hidden = YES;                   }    }// 这个方法只会调用一次- (void)awakeFromNib{    // 手动设置文字的最大宽度(让label能够计算出自己最真实的尺寸)    self.text_Label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;}- (CGFloat)cellHeight{//    self.text_Label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;        [self layoutIfNeeded];        CGFloat cellHeight = 0;    if (self.status.picture) { //有配图        cellHeight = CGRectGetMaxY(self.pictureImageView.frame) + 10;    }else{  // 无配图        cellHeight = CGRectGetMaxY(self.text_Label.frame) + 10;    }    return cellHeight;}@end

ViewController文件

#import "ViewController.h"#import "MJExtension.h"#import "ZYStatusCell.h"#import "ZYStatus.h"@interface ViewController ()/** 所有的微博 */@property (nonatomic,strong) NSArray *statuses;@end@implementation ViewController- (NSArray *)statuses{    if (_statuses == nil) {        //加载plist中的数据到,模型ZYStatus中        _statuses = [ZYStatus mj_objectArrayWithFilename:@"statuses.plist"];    }        return _statuses;}- (void)viewDidLoad {    [super viewDidLoad];        // cell的估算高度(作用: 性能优化,减少heightForRowAtIndexPath方法的调用次数)    // 假如一个cell的高度为100.iphone6的高度为650,所以会打印7次heightForRowAtIndexPath方法,来快速\    估算有多少cell要显示    self.tableView.estimatedRowHeight = 100;    }#pragma -mark 数据源方法NSString *ID = @"status";- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return self.statuses.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{        // 到缓存池中查看是否有可循环利用的cell    ZYStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];        // 传递模型数据    cell.status = self.statuses[indexPath.row];        return cell;}ZYStatusCell *cell;#pragma -mark 代理方法// 系统之所以调用多次这个方法,为了计算contentSize的滚动范围,为了用户体验,计算滚动条的长度.- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    if (cell == nil) {        cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    cell.status = self.statuses[indexPath.row];    return cell.cellHeight;    }@end





原创粉丝点击