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