iOS开发之有趣的UI —— iOS8之前和之后的自定义不等高cell

来源:互联网 发布:淘宝网商家服务热线 编辑:程序博客网 时间:2024/05/16 17:36

C语言学习: iOS开发分分钟搞定C语言
OC语言学习: iOS开发核心语言Objective C
分享400G iOS学习资料
获取途径:新浪微博 关注➕私信 : 极客James

这里写图片描述

一、iOS8之前通过storyboard和自动布局完成自定义非等高cell

通过微博案例来分析iOS8之前通过storyboard和自动布局完成自定义非等高cell。
通过上一篇的MVVM设计模式我们已经通过将视图模型和数据模型进行了整合,然控制器直接通过数据模型来直接掉视图模型,这种方式大大的提够了编码效率和程序效率。

项目实施思路:
核心:通过设置最后一个元素的高度以及和底部的约束来控制不等高cell的高度。

1.创建项目,导入图片及plist文件。
2.创建数据模型,进行数据转模型
3.创建继承自UITableViewCell的自定义cell模型ZJStatusCell文件
4.创建storyboard,利用autolayout进行自动布局,并且让storyboard和ZJStatusCell建立相应联系
5.在控制器中完成相应的数据源方法

项目效果图:
这里写图片描述
代码实现过程:
(1)创建项目导入素材
(2)创建继承自ZJObjectiv的ZJStatus数据模型
在ZJStatus.h中

/*********显示数据模型********//** 头像 */@property (nonatomic ,copy)NSString *icon;/** 昵称 */@property (nonatomic ,copy)NSString *name;/** vip */@property (nonatomic ,assign)BOOL vip;/** 文字 */@property (nonatomic ,copy)NSString *text;/** 配图 */@property (nonatomic ,copy)NSString *picture;

在ZJStatus.m文件中 不做任何操作

(3)创建继承自UITableViewCell的视图模型ZJStatusView进行子控件布局及数据重写等操作
在ZJStatusView.h文件中
导入@class ZJStatus;
加载ZJStatus的所有属性并声明
声明一个高度cellHeight

@class ZJStatus;@interface ZJStatusCell : UITableViewCell/** status的数据 */@property (nonatomic,strong) ZJStatus *status; // 定义一个cell的高度- (CGFloat)height;

在ZJStatusView.m中

#import "ZJStatus.h"#define KNameFont [UIFont systemFontOfSize:17]#define KTextFont [UIFont systemFontOfSize:14]@interface ZJStatusCell ()// storyboard中的布局与ZJStatusCell建立联系/** 头像 */@property (nonatomic ,weak)IBOutlet UIImageView *iconImageView;/** 昵称 */@property (nonatomic ,weak)IBOutlet UILabel *nameLabel;/** vip */@property (nonatomic ,weak)IBOutlet UIImageView * vipImageView;/** 文字 */@property (nonatomic ,weak)IBOutlet UILabel *TEXTLabel;/** 图片 */@property (nonatomic ,weak)IBOutlet UIImageView *pictureImageView;/** 配图的顶部*/@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cellHeight;@end@implementation ZJStatusCellCGFloat margin = 10;- (void)awakeFromNib{ // 设置文字的最大边距    self.TEXTLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width + margin;}- (CGFloat)height{    // 先强制布局子控件    [self layoutIfNeeded];    // 设置图片的高度    if (self.status.picture) {// 有图片     return CGRectGetMaxY(self.pictureImageView.frame) + margin;    }    else{// 没有图片        return CGRectGetMaxY(self.TEXTLabel.frame) + margin;    }}- (void)setStatus:(ZJStatus *)status{    _status = status;    self.iconImageView.image = [UIImage imageNamed:status.icon];    self.nameLabel.text = status.name;    self.TEXTLabel.text = status.text;    // 如果有图片    if (status.picture) {        self.pictureImageView.hidden = NO;        self.pictureImageView.image = [UIImage imageNamed:status.picture];    }   else { // 没有图片       self.pictureImageView.hidden = YES;      }    // vip 图标    if (status.vip) {        self.vipImageView.hidden = NO;        self.nameLabel.textColor = [UIColor orangeColor];    }else{        self.vipImageView.hidden = YES;        self.nameLabel.textColor = [UIColor blackColor];    }}

在控制器中完成的操作:

#import "MJExtension.h"#import "ZJStatus.h"#import "ZJStatusCell.h"@interface ViewController ()@property (nonatomic ,strong)NSArray *statuses;@end@implementation ViewControllerNSString *ID = @"status";- (void)viewDidLoad {    [super viewDidLoad];   //  先进行预估高度self.tableView.estimatedRowHeight = 200;   }- (NSArray *)statuses{    if (!_statuses) {// 数据数组转模型数组   _statuses = [ZJStatus objectArrayWithFilename:@"statuses.plist"];    }    return _statuses;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return self.statuses.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    ZJStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 取出数据    cell.status = self.statuses[indexPath.row];    return cell;}#pragma mark 代理方法ZJStatusCell *cell;- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    if(!cell){        cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    // 设置数据    cell.status = self.statuses[indexPath.row];    // 显示行高    return cell.height;}

完成以上步骤就可以完成iOS8之前通过storyboard实现不等高cell的实现。

注意点:
(1)在控制器中
在视图加载完毕之后要先预估cell的高度
self.tableView.estimatedRowHeight = 200;

(2)在实现cell行高的代理中

ZJStatusCell *cell;- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    if(!cell){        cell = [tableView dequeueReusableCellWithIdentifier:ID];    }    // 设置数据    cell.status = self.statuses[indexPath.row];    // 显示行高    return cell.height; }

(3)在视图中
加载storyboard时确定文字的边距

- (void)awakeFromNib{  // 设置文字的最大边距    self.TEXTLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width + margin;}

(4)在height中

- (CGFloat)height{    // 1.先强制布局子控件    [self layoutIfNeeded];    // 设置图片的高度    if (self.status.picture) {// 有图片     return CGRectGetMaxY(self.pictureImageView.frame) + margin;    }    else{// 没有图片        return CGRectGetMaxY(self.TEXTLabel.frame) + margin;    }}

二、iOS8之后通过storyboard和自动布局的方式实现不等高sell

与上一个分享代码类似,不同之处在
(1)在控制器中
viewDidLoad加载完视图后

    // 这两个都必须有    // 设置cell自动高度    self.tableView.rowHeight = UITableViewAutomaticDimension;   // 估算高度    self.tableView.estimatedRowHeight = 44;

(2)不用再视图模型中进行强制布局子控件
(3)通过在视图模型中判断是否有图片来进行高度的确定

三.布局自定义不等高cell注意事项

1.先确定布局方式
2.不同布局方式有不同的方式
3.纯代码布局,注意MVVM的设计模式以及一些高度的 计算
4.storyboard布局,区分iOS8之前和之后的操作。
iOS8之前操作需要在视图加载后定义一个cell的估计高度,在代理方法中先定义全局变量ID 然后进行判断cell是否为空来加载cell,在视图模型中当程序一启动调用awakeframenib方法中要设置文字的最大边距 -

(void)awakeFromNib{ // 设置文字的最大边距self.TEXTLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width + margin;}

5.在定义的height方法中要先强制布局,然后再进行有无图片的判断。

0 0
原创粉丝点击