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

版权声明:本文为博主原创文章,转载请注明出处,仅用于学习交流和资源共享。关注新浪微博:极客James https://blog.csdn.net/zc639143029/article/details/48832617

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 ZJStatusCell

CGFloat 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 ViewController


NSString *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方法中要先强制布局,然后再进行有无图片的判断。

猜你喜欢

转载自blog.csdn.net/zc639143029/article/details/48832617