UITableView之(五):自定义UITableViewCell

几乎所有的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的方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值