UI学习笔记---第十一天UITableView表视图高级-自定义cell

自定义cell,多类型cell混合使用,cell自适应高度

自定义cell就是创建一个UITableViewCell的子类

把cell上的空间创建都封装在子类中,简化viewController中的代码

cell中的空间如何显示Model中的信息

cell中声明一个Model类型的属性,viewController中获取到Model对象后赋值给cell的Model属性

cell中重写Model的setter方法,把Model对象中的内容重新赋值给各个控件

M和V不直接通信,C负责M和V之间进行通信

多类型cell混合使用

通常我们会在tableView:cellForRowAtIndexPath:方法中根据不同的Model来决定使用什么类型的cell

每种类型的cell要定义不同的重用标识符

cell重用的时候会根据重用标识从重用队列中取用那种类型的cell

cell自适应高度

实际开发中经常要让cell根据Model中文本的长短动态的更改高度

获取文本高度 ---计算一段文本在限定宽高内所占矩形大小

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary*)attributes context:(NSStringDrawingContext *)context

计算文本高度是所用字体要和label显示时所用的字体一致

label的宽度要和计算时所用的限定宽度一致这样才能保证文本显示在label中时,label的高度恰巧够

cell自适应高度

tableView:heightForRowAtIndexPath:⽅法要比

tableView:cellForRowAtIndexPath先执行。

所以要提前计算好每行cell需要多少高度

练习代码

AppDalegate.m中创建根表视图控制器,导航控制器

    RootTableViewController *rootVC = [[RootTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
    UINavigationController *ngVc = [[UINavigationController alloc] initWithRootViewController:rootVC];
    self.window.rootViewController = ngVc;
    [ngVc release];
    [rootVC release];

RootTableViewController控制器类中代码

//.h中代码
#import <UIKit/UIKit.h>

@interface RootTableViewController : UITableViewController

{
    NSMutableArray *_studentsArray;
}
@end
//.m中代码
#import "RootTableViewController.h"
#import "StudentCell.h"
#import "Student.h"
#import "SecondCell.h"
@interface RootTableViewController ()

@end

@implementation RootTableViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        self.navigationItem.title =@"通讯录";
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //这是一个单例,用来取文件路径
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Students" ofType:@"plist"];
  
    NSArray *students = [[NSArray alloc] initWithContentsOfFile:filePath];

    _studentsArray = [[NSMutableArray alloc] initWithCapacity:[students count]];
    for (int i = 0; i<[students count]; i++) {
        NSDictionary *dic = [students objectAtIndex:i];
        Student *stu = [[Student alloc] init];
        //使用kvc
        [stu setValuesForKeysWithDictionary:dic];
        [_studentsArray addObject:stu];
        [stu release];
    }
    [students release];
    NSLog(@"%@",_studentsArray);
    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
    
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [_studentsArray count];
}



/////********************一种方法************************
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//{
//    static NSString *identifier = @"cell";
//    
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
//    if (cell == nil) {
//        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
//    }
//    //创建一个label
//    [[cell.contentView viewWithTag:1000] removeFromSuperview];
//    UILabel *sexlabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, 100, 40)];
//    sexlabel.tag = 1000;
//    [cell.contentView addSubview:sexlabel];
//    [sexlabel release];
//    
//    
//    NSDictionary *student = [_studentsArray objectAtIndex:indexPath.row];
//    
//    cell.textLabel.text = [student objectForKey:@"name"];
//    sexlabel.text = [student objectForKey:@"sex"];
//    
//    // Configure the cell...
//    
//    return cell;
//}
//
////********************方法二*********************
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//{
//    static NSString *identifier = @"cell";
//    
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
//    if (cell == nil) {
//        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
//        //创建一个cell创建一个label,第一种方法的优化,第一种方法一直开辟空间释放空间,占用系统资源
//    [[cell.contentView viewWithTag:1000] removeFromSuperview];
//    UILabel *sexlabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, 100, 40)];
//    sexlabel.tag = 1000;
//    [cell.contentView addSubview:sexlabel];
//    [sexlabel release];
//    }
//    //if中的sexlabel是一个局部变量,需要在外面重写一个label接受tag=1000的label
//    UILabel *sexlabel = (UILabel *)[cell.contentView viewWithTag:1000];
//    
//    NSDictionary *student = [_studentsArray objectAtIndex:indexPath.row];
//    
//    cell.textLabel.text = [student objectForKey:@"name"];
//    sexlabel.text = [student objectForKey:@"sex"];
//    
//    
//    // Configure the cell...
//    
//    return cell;
//}
/////***************第三种建一个UITableViewCell子类*******************
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Student *stu = [_studentsArray objectAtIndex:indexPath.row];
    if ([stu.sex isEqualToString:@""]) {
        static NSString *identifier = @"cell1";
        StudentCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
        if (cell == nil) {
            cell = [[[StudentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
        }
        cell.stu = _studentsArray[indexPath.row];
        return cell;
    }else{
        static NSString *identifier = @"cell";
        
        SecondCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
        if (cell == nil) {
            cell = [[[SecondCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
            
        }

        cell.stu = _studentsArray[indexPath.row];

        
        // Configure the cell...
        
        return cell;

    }
    
//    static NSString *identifier = @"cell";
//    
//    SecondCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
//    if (cell == nil) {
//        cell = [[[SecondCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
//
//    }
//
//
////    Student *student = [_studentsArray objectAtIndex:indexPath.row];
////    [cell setStu:student];
//    cell.stu = _studentsArray[indexPath.row];
////    cell.nameLabel.text = student.name;
////    cell.sexLabel.text = student.sex;
////    cell.phoneLabel.text = student.phone;
////    cell.photoImageView.image = [UIImage imageNamed:student.photo];
//    
//
//    
//    
//    // Configure the cell...
//    
//    return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//    CGFloat height = Studentcell;
    Student *stu = [_studentsArray objectAtIndex:indexPath.row];
    CGRect rect = [stu.hobby boundingRectWithSize:CGSizeMake(250, 10000) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:18],NSFontAttributeName, nil] context:nil];
    if ([stu.sex isEqualToString:@""]) {
        

        
        return 92+rect.size.height+5;
    }else{
        
     return 92+rect.size.height+5;
    }
   
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

自定义cell----StudentCell中代码

//.h中代码
#import <UIKit/UIKit.h>
#import "Student.h"
@interface StudentCell : UITableViewCell
@property (nonatomic,retain) UILabel *nameLabel;
@property (nonatomic,retain) UILabel *sexLabel;
@property (nonatomic,retain) UILabel *phoneLabel;
@property (nonatomic,retain) UIImageView *photoImageView;
@property (nonatomic,retain) UILabel *hobbyLabel;
//对cell中需要显示的数据进行封装,创建一个Student  Model类
@property (nonatomic,retain) Student *stu;


@end
//.m中代码
#import "StudentCell.h"

@implementation StudentCell
-(void)dealloc
{
    [_photoImageView release];
    [_nameLabel release];
    [_sexLabel release];
    [_phoneLabel release];
    [super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        //自定义cell
        self.photoImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(5, 2, 50, 50)] autorelease];
        self.nameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(70, 2, 100, 20)] autorelease];
        self.sexLabel = [[[UILabel alloc] initWithFrame:CGRectMake(70, 32, 100, 20)] autorelease];
        self.phoneLabel = [[[UILabel alloc] initWithFrame:CGRectMake(70, 62, 100, 20)] autorelease];
        self.hobbyLabel = [[[UILabel alloc] initWithFrame:CGRectMake(70, 92, 250, 20)] autorelease];
        //给hobbylabel设定一个字号,在表视图控制器里面直接可以使用
        self.hobbyLabel.font = [UIFont systemFontOfSize:18];
        //让它自适应高度,把行数设为0    
        self.hobbyLabel.numberOfLines = 0;
        
        
        [self.contentView addSubview:_photoImageView];
        [self.contentView addSubview:_nameLabel];
        [self.contentView addSubview:_sexLabel];
        [self.contentView addSubview:_phoneLabel];
        [self.contentView addSubview:_hobbyLabel];
        
        // Initialization code
    }
    return self;
}

- (void)awakeFromNib
{
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}
//重写setter方法
- (void)setStu:(Student *)stu
{
    self.nameLabel.text = stu.name;
    self.sexLabel.text = stu.sex;
    self.phoneLabel.text = stu.phone;
    
    self.photoImageView.image = [UIImage imageNamed:stu.photo];
    //设置爱好自定义高度
    CGRect rect = [stu.hobby boundingRectWithSize:CGSizeMake(250, 10000) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:self.hobbyLabel.font,NSFontAttributeName, nil] context:nil];
    self.hobbyLabel.frame = CGRectMake(70, 92, 250, rect.size.height);
    self.hobbyLabel.text = stu.hobby;
    
}

@end

自定义另一个cell----SecondCell

//.h中代码
#import <UIKit/UIKit.h>
#import "Student.h"
@interface SecondCell : UITableViewCell
@property (nonatomic,retain) UILabel *nameLabel;
@property (nonatomic,retain) UILabel *sexLabel;
@property (nonatomic,retain) UILabel *phoneLabel;
@property (nonatomic,retain) UIImageView *photoImageView;
@property (nonatomic,retain) UILabel *hobbyLabel;

@property (nonatomic,retain) Student *stu;
@end
//.m中代码
#import "SecondCell.h"

@implementation SecondCell
-(void)dealloc
{
    [_photoImageView release];
    [_nameLabel release];
    [_sexLabel release];
    [_phoneLabel release];
    [_hobbyLabel release];
    [super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        //自定义cell
        self.photoImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(260, 2, 50, 50)] autorelease];
        self.nameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(150, 2, 100, 20)] autorelease];
        self.sexLabel = [[[UILabel alloc] initWithFrame:CGRectMake(150, 32, 100, 20)] autorelease];
        self.phoneLabel = [[[UILabel alloc] initWithFrame:CGRectMake(150, 62, 100, 20)] autorelease];
        self.hobbyLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 92, 250, 20)] autorelease];
        self.hobbyLabel.font = [UIFont systemFontOfSize:18];
        
        
        [self.contentView addSubview:_photoImageView];
        [self.contentView addSubview:_nameLabel];
        [self.contentView addSubview:_sexLabel];
        [self.contentView addSubview:_phoneLabel];
        [self.contentView addSubview:_hobbyLabel];
        // Initialization code
    }
    return self;
}

- (void)awakeFromNib
{
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    
    // Configure the view for the selected state
}
//重写setter方法
- (void)setStu:(Student *)stu
{
    self.nameLabel.text = stu.name;
    self.sexLabel.text = stu.sex;
    self.phoneLabel.text = stu.phone;
    self.photoImageView.image = [UIImage imageNamed:stu.photo];
    CGRect rect = [stu.hobby boundingRectWithSize:CGSizeMake(250, 10000) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:18],NSFontAttributeName, nil] context:nil];

    self.hobbyLabel.frame = CGRectMake(10, 92, 250, rect.size.height);
    self.hobbyLabel.text = stu.hobby;
    
}

@end

Model类-----Student

//.h中代码
#import <Foundation/Foundation.h>

@interface Student : NSObject
@property (nonatomic,retain) NSString *name;
@property (nonatomic,retain) NSString *sex;
@property (nonatomic,retain) NSString *phone;
@property (nonatomic,retain) NSString *photo;
@property (nonatomic,retain) NSString *hobby;

//- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex phone:(NSString *)phone photo:(NSString *)photo hobby:(NSString *)hobby;
//
//- (instancetype)initWithDictionary:(NSDictionary *)stuInfoDic;
@end
//.m中代码
#import "Student.h"

@implementation Student
-(void)dealloc
{
    [_name release];
    [_sex release];
    [_phone release];
    [_photo release];
    [_hobby release];
    [super dealloc];
}
//用KVC取值,不用初始化方法
//- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex phone:(NSString *)phone photo:(NSString *)photo hobby:(NSString *)hobby
//{
//    self = [super init];
//    if (self) {
//        self.name = name;
//        self.sex = sex;
//        self.phone = phone;
//        self.photo = photo;
//        self.hobby = hobby;
//    }
//    return self;
//}
//
//- (instancetype)initWithDictionary:(NSDictionary *)stuInfoDic
//{
//    self = [super init];
//    if (self) {
//        self.name = [stuInfoDic objectForKey:@"name"];
//        self.sex = [stuInfoDic objectForKey:@"sex"];
//        self.phone = [stuInfoDic objectForKey:@"phone"];
//        self.photo = [stuInfoDic objectForKey:@"photo"];
//        self.hobby = [stuInfoDic objectForKey:@"hobby"];        
//    }
//    return self;
//}

-(void)setValue:(id)value forUndefinedKey:(NSString *)key
{

}
@end

数据来源是创建一个plist文件

查看plist源代码

原文地址:https://www.cnblogs.com/limicheng/p/3863805.html