您的位置:首页 > 产品设计 > UI/UE

UITableView之(五):自定义UITableViewCell

2016-09-12 11:23 483 查看
几乎所有的tableViewCell都是采用自定义的方式进行展示UI的。自定义tableViewCell是学习tableView的重点和难点。

重点:经常用到

难点:1、复杂cell的显示细节非常多

           2、控制好cell的重用,cell的异常显示往往和重用有很大的关系,这也是bug的重灾区

           3、可变高度的计算,很多情况下自定义的cell的高度都不会完全一致,样式也多种多样

自定义cell的步骤:

1、继承自UITableViewCell

2、在初始化方法中设置需要显示的控件

3、在layoutSubviews中设置控件显示的位置

4、从封装的思路出发,对外只提供设置模型的属性

5、在.m中实现模型的setter的方法,cell的模型一有值,就进行对应控件的显示

6、如果cell的高度不固定,还要提供设置高度的方法。

其中设置高度的方法有很多中:

获取高度的基本思想:固定高度 + 可变高度

1、在cell提供高度的类方法

+ (CGFloat)cellWithHeight:(CGFloat)height
{
return 50 + height;
}

//声明私有方法计算可变的高度
- (CGFloat)heightWithString:(NSString *)aString
{
CGRect r = [aString boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.tableView.frame) - 10, maxfloat)
options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15.0f]} context:nil];

return r.size.height + 10;
}

//调用代理方法,计算cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//    拿到模型中获取高度的字符串
NSString * s = self.dataArray[indexPath.row];
// 使用类方法计算高度
return [xxxCell cellWithHeight: [self heightWithString:s]];
}


2、在viewController中创建获取高度的方法

// 贴一段代码
// 设置每个cell对应的高度 固定高度 + 可变高度 这里的可变高度为字符串
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat ch = [self cellHeightWithAttendanceDetailModel:self.dataArray[indexPath.row]];
CGFloat totalH = ch + 54;
return totalH;
}

// 获取cell对应模型中字符串的高度
- (CGFloat)cellHeightWithAttendanceDetailModel:(TeacherAttendanceDetailModel *)detailModel
{
CGSize maxSize = CGSizeMake(self.view.width - 40, MAXFLOAT);

CGFloat textH = [detailModel.detailTypeName textRectWithFont:[UIFont systemFontOfSize:13]
maxSize:maxSize mode:(NSLineBreakByCharWrapping)].height;

 return textH;
}


3、提供自定义cell模型控件对应的frame模型

在viewController中获取的模型就是frame模型,frame模型里面包含的是真正要模型

在frame模型里面设置的是:每个cell控件对应的frame以及cell 的最终高度

如:一段非常简单的设置

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> // 引入此头文件,否则没有CGRect

@class FeedbackQuestionsList;
@interface FeedbackFrame : NSObject

/** 模型*/
@property (strong, nonatomic)FeedbackQuestionsList *question;

@property (assign, nonatomic)CGRect titleF;
@property (assign, nonatomic)CGRect lineF;
@property (assign, nonatomic)CGFloat cellHeight;

@end

#import "FeedbackFrame.h"
#import "FeedbackQuestionsList.h"

@implementation FeedbackFrame

// 使用setter方法设置模型的对应位置
- (void)setQuestion:(FeedbackQuestionsList *)question
{
_question = question;

CGFloat padding = 10;
CGFloat cellW = [UIScreen mainScreen].bounds.size.width;

CGFloat titleX = padding;
CGFloat titleY = padding;
NSString *contentString = [NSString stringWithFormat:@"%zd、%@", question.index, question.content];
CGSize titleSize = [contentString textRectWithFont:[UIFont systemFontOfSize:15]
maxSize:CGSizeMake(cellW - 2 * padding, MAXFLOAT) mode:(NSLineBreakByWordWrapping)];
_titleF = CGRectMake(titleX, titleY, titleSize.width, titleSize.height);

CGFloat lineX = titleX;
CGFloat lineY = CGRectGetMaxY(_titleF) + padding;
CGFloat lineW = cellW - padding;
CGFloat lineH = 1;
_lineF = CGRectMake(lineX, lineY, lineW, lineH);

// 获取cell的高度
_cellHeight = CGRectGetMaxY(_lineF);
}
@end


cell中的模型即为frame模型

- (void)setFeebbackFrame:(FeedbackFrame *)feebbackFrame
{
_feebbackFrame = feebbackFrame;
FeedbackQuestionsList *question = feebbackFrame.question;

self.titleLabel.text = [NSString stringWithFormat:@"%zd、%@", question.index, question.content];
}


在viewController中获取frame模型并进行cell的设置

// 获取到网络数据进行模型的装换
NSDictionary *dic = responseObject.result;
NSArray *array = dic[@"data"];
if (array.count) {

for (NSDictionary *dic in array) {
QuestionsFrame *quesFrame = [[QuestionsFrame alloc] init];
FeedbackQuestionsList *question = [FeedbackQuestionsList cellWithQuestionsDic:dic];
quesFrame.questions = question;
[self.questionsArray addObject:quesFrame];
}
}


tableView中进行赋值,同时

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FeedbackQuestionListCell *cell = [FeedbackQuestionListCell questionCellWithTableView:tableView];

cell.questionFrame = self.questionsArray[indexPath.row];

return cell;
}


4、使用masonry获取cell的高度

使用masonry自动布局完成后,调用[cell layoutIfNeeded];

然后使用:    CGRectGetMaxY(最后一个控件); 获取到cell的实际高度。

5、使用Masonry进行自定义Cell的创建和使用Xib、StoryBoard一样,label可以不设置高度,有系统自动进行设置。

我们只需要计算出固定高度和可变高度即可。采取上面2的方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: