zoukankan      html  css  js  c++  java
  • 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源代码

  • 相关阅读:
    Git哲学与使用
    save
    http://www.onvif.org/onvif/ver20/util/operationIndex.html
    图标
    C#高性能大容量SOCKET并发(一):IOCP完成端口例子介绍(转)
    一种基于PTP 协议的局域网高精度时钟同步方法(转)
    WPF中的数据模板(DataTemplate)(转)
    WPF中的ControlTemplate(控件模板)(转)
    也来说说C#异步委托(转)
    C#委托的介绍(delegate、Action、Func、predicate)(转)
  • 原文地址:https://www.cnblogs.com/limicheng/p/3863805.html
Copyright © 2011-2022 走看看