IOS TableView的Cell高度自适应,UILabel自动换行适应 table里控件位置自适应

本文详细介绍了如何在iOS应用中使用纯代码实现自适应换行的UILabel,并结合UITableView动态调整高度以适应内容,适用于创建自适应的表格视图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

部分转载自:http://blog.youkuaiyun.com/swingpyzf/article/details/18093959

需求:
1、表格里的UILable要求自动换行

2、创建的tableViewCell的高度会自动适应内容的高度


一、用xcode构建项目,创建一个有tableView的视图,用纯代码的形式实现:

1、创建一个UIViewController类,定义一个UITableView,实现TableView的委托和数据源协议

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    //  
    //  TableViewController.h  
    //  AdaptiveCell  
    //  
    //  Created by swinglife on 14-1-10.  
    //  Copyright (c) 2014年 swinglife. All rights reserved.  
    //  
      
    #import <UIKit/UIKit.h>  
      
    @interface TableViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{  
          
    }  
      
    @property (nonatomic,retain) UITableView *tableView;  
      
    @end  


2、实现UITableView对象的初始化,声明一个tableData的数组对象用来保存tableView中得数据

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    #import "TableViewController.h"  
      
    @interface TableViewController (){  
        NSMutableArray *tableData;  //tableView数据存放数组  
    }  
      
    @end  
      
    @implementation TableViewController  
      
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
    {  
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
        if (self) {  
            tableData = [[NSMutableArray alloc] init];  
        }  
        return self;  
    }  
      
    - (void)viewDidLoad  
    {  
        [super viewDidLoad];  
        [self initTableView];  
    }  
      
    //初始化tableView;  
    -(void)initTableView{  
        CGRect frame = self.view.frame;  
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height)];  
        //代理类  
        _tableView.delegate = self;  
        //数据源  
        _tableView.dataSource = self;  
        [self.view addSubview:_tableView];  
    }  


3、创建自定义的UITableViewCell类,声明需要用到的控件对象和方法:

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    #import <UIKit/UIKit.h>  
      
    @interface TableViewCell : UITableViewCell{  
      
    }  
      
    //用户名  
    @property(nonatomic,retain) UILabel *name;  
    //用户介绍  
    @property(nonatomic,retain) UILabel *introduction;  
    //用户头像  
    @property(nonatomic,retain) UIImageView *userImage;  
      
    //给用户介绍赋值并且实现自动换行  
    -(void)setIntroductionText:(NSString*)text;  
    //初始化cell类  
    -(id)initWithReuseIdentifier:(NSString*)reuseIdentifier;  
    @end  


4、初始化Cell的用户控件,实现方法:

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    //  
    //  TableViewCell.m  
    //  AdaptiveCell  
    //  
    //  Created by swinglife on 14-1-10.  
    //  Copyright (c) 2014年 swinglife. All rights reserved.  
    //  
      
    #import "TableViewCell.h"  
      
    @implementation TableViewCell  
      
    -(id)initWithReuseIdentifier:(NSString*)reuseIdentifier{  
        self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];  
        if (self) {  
            [self initLayuot];  
        }  
        return self;  
    }  
    //初始化控件  
    -(void)initLayuot{  
        _name = [[UILabel alloc] initWithFrame:CGRectMake(71, 5, 250, 40)];  
        [self addSubview:_name];  
        _userImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 66, 66)];  
        [self addSubview:_userImage];  
        _introduction = [[UILabel alloc] initWithFrame:CGRectMake(5, 78, 250, 40)];  
        [self addSubview:_introduction];  
    }  
      
    //赋值 and 自动换行,计算出cell的高度  
    -(void)setIntroductionText:(NSString*)text{  
        //获得当前cell高度  
        CGRect frame = [self frame];  
        //文本赋值  
        self.introduction.text = text;  
        //设置label的最大行数  
        self.introduction.numberOfLines = 10;  
        CGSize size = CGSizeMake(300, 1000);  
        CGSize labelSize = [self.introduction.text sizeWithFont:self.introduction.font constrainedToSize:size lineBreakMode:NSLineBreakByClipping];  
        self.introduction.frame = CGRectMake(self.introduction.frame.origin.x, self.introduction.frame.origin.y, labelSize.width, labelSize.height);  
          
        //计算出自适应的高度  
        frame.size.height = labelSize.height+100;  
          
        self.frame = frame;  
    }  
      
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated  
    {  
        [super setSelected:selected animated:animated];  
      
    }  
      
    @end  


5、现在需要一个存放数据对象的模型类,创建一个UserModel用来封装数据

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    #import <Foundation/Foundation.h>  
      
    @interface UserModel : NSObject  
      
    //用户名  
    @property (nonatomic,copy) NSString *username;  
    //介绍  
    @property (nonatomic,copy) NSString *introduction;  
    //头像图片路径  
    @property (nonatomic,copy) NSString *imagePath;  
      
    @end  


6、现在需要一些数据,在TableViewController.m文件中实现数据的创建:

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    //我需要一点测试数据,直接复制老项目东西  
    -(void)createUserData{  
        UserModel *user = [[UserModel alloc] init];  
        [user setUsername:@"胖虎"];  
        [user setIntroduction:@"我是胖虎我怕谁!!我是胖虎我怕谁!!我是胖虎我怕谁!!"];  
        [user setImagePath:@"panghu.jpg"];  
        UserModel *user2 = [[UserModel alloc] init];  
        [user2 setUsername:@"多啦A梦"];  
        [user2 setIntroduction:@"我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!"];  
        [user2 setImagePath:@"duolaameng.jpg"];  
        UserModel *user3 = [[UserModel alloc] init];  
        [user3 setUsername:@"大雄"];  
        [user3 setIntroduction:@"我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,"];  
        [user3 setImagePath:@"daxiong.jpg"];  
      
          
        [tableData addObject:user];  
        [tableData addObject:user2];  
        [tableData addObject:user3];  
    }  

还需要在viewDidLoad中调用上面这个方法来创建数据

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    - (void)viewDidLoad  
    {  
        [super viewDidLoad];  
        [self initTableView];  
        [self createUserData];  
    }  




7、实现TableView的

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

方法为cell赋值

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{  
        return 1;  
    }  
      
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{  
        return [tableData count];  
    }  
      
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
    {  
        //指定cellIdentifier为自定义的cell  
        static NSString *CellIdentifier = @"Cell";  
        //自定义cell类  
        TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
        if (cell == nil) {  
            cell = [[TableViewCell alloc] initWithReuseIdentifier:CellIdentifier];  
        }  
        UserModel *user = [tableData objectAtIndex:indexPath.row];  
        cell.name.text = user.username;  
        [cell.userImage setImage:[UIImage imageNamed:user.imagePath]];  
        [cell setIntroductionText:user.introduction];  
        return cell;  
    }  


8、最后需要将cell的高度返回给

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath方法:

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{  
        TableViewCell *cell = [self tableView:_tableView cellForRowAtIndexPath:indexPath];  
        return cell.frame.size.height;  
    }  


这样TableViewController.m中得所有代码:

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片

    //  
    //  TableViewController.m  
    //  AdaptiveCell  
    //  
    //  Created by swinglife on 14-1-10.  
    //  Copyright (c) 2014年 swinglife. All rights reserved.  
    //  
      
    #import "TableViewController.h"  
    #import "UserModel.h"  
    #import "TableViewCell.h"  
      
    @interface TableViewController (){  
        NSMutableArray *tableData;  //tableView数据存放数组  
    }  
      
    @end  
      
    @implementation TableViewController  
      
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
    {  
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
        if (self) {  
            tableData = [[NSMutableArray alloc] init];  
        }  
        return self;  
    }  
      
    - (void)viewDidLoad  
    {  
        [super viewDidLoad];  
        [self initTableView];  
        [self createUserData];  
    }  
      
    //初始化tableView;  
    -(void)initTableView{  
        CGRect frame = self.view.frame;  
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height)];  
        //代理类  
        _tableView.delegate = self;  
        //数据源  
        _tableView.dataSource = self;  
        [self.view addSubview:_tableView];  
    }  
      
    //我需要一点测试数据,直接复制老项目东西  
    -(void)createUserData{  
        UserModel *user = [[UserModel alloc] init];  
        [user setUsername:@"胖虎"];  
        [user setIntroduction:@"我是胖虎我怕谁!!我是胖虎我怕谁!!我是胖虎我怕谁!!"];  
        [user setImagePath:@"panghu.jpg"];  
        UserModel *user2 = [[UserModel alloc] init];  
        [user2 setUsername:@"多啦A梦"];  
        [user2 setIntroduction:@"我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!我是多啦A梦我有肚子!!"];  
        [user2 setImagePath:@"duolaameng.jpg"];  
        UserModel *user3 = [[UserModel alloc] init];  
        [user3 setUsername:@"大雄"];  
        [user3 setIntroduction:@"我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,我是大雄我谁都怕,"];  
        [user3 setImagePath:@"daxiong.jpg"];  
      
          
        [tableData addObject:user];  
        [tableData addObject:user2];  
        [tableData addObject:user3];  
    }  
      
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{  
        TableViewCell *cell = [self tableView:_tableView cellForRowAtIndexPath:indexPath];  
        return cell.frame.size.height;  
    }  
      
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{  
        return 1;  
    }  
      
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{  
        return [tableData count];  
    }  
      
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
    {  
        //指定cellIdentifier为自定义的cell  
        static NSString *CellIdentifier = @"Cell";  
        //自定义cell类  
        TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
        if (cell == nil) {  
            cell = [[TableViewCell alloc] initWithReuseIdentifier:CellIdentifier];  
        }  
        UserModel *user = [tableData objectAtIndex:indexPath.row];  
        cell.name.text = user.username;  
        [cell.userImage setImage:[UIImage imageNamed:user.imagePath]];  
        [cell setIntroductionText:user.introduction];  
        return cell;  
    }  
      
    - (void)didReceiveMemoryWarning  
    {  
        [super didReceiveMemoryWarning];  
    }  
      
    @end  


总结:这种方式是通过计算出UILabel自动换行后的高度后,通过-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 方法将高度返回给TableView然后构建cell的高度。

控件自适应:原理 先将每行的高度算出来,然后添加进一个字典,cell里的控件位置根据得到的高度动态调整即可以达到控件自适应的需求

-(void)getheight///获取每行的高度,将其填入数组
{
    if(hasreplay<=1)
    {
        return;
    }
    NSMutableArray * MYfeed=[[feedbackDic objectForKey:@"detail"]objectForKey:@"detaillist" ];
   
    for(int i=0;i<[MYfeed count];i++)
    {
        NSString *KEYID=[NSString stringWithFormat:@"%d",i ];
    NSMutableDictionary *detail=[MYfeed objectAtIndex:i];
    NSString *content=[NSString stringWithFormat:@"%@",[detail objectForKey:@"content"] ];
        
      
        UILabel *titlecontentt=[[UILabel alloc]init];
       
        titlecontentt.font=[UIFont systemFontOfSize:12];
        titlecontentt.lineBreakMode = UILineBreakModeWordWrap;//自动换行
        titlecontentt.numberOfLines = 0;
       
        
        CGSize labelSize = {0, 0};
        
        labelSize = [content sizeWithFont:[UIFont systemFontOfSize:12]
                     
                         constrainedToSize:CGSizeMake(200.0, 5000)
                     
                             lineBreakMode:UILineBreakModeWordWrap];
        
         titlecontentt.frame = CGRectMake(-1000, -1000, 300, labelSize.height);/////获取动态高度
        
        float Y=titlecontentt.frame.size.height+40;
        NSString *HEI=[NSString stringWithFormat:@"%f",Y];
        [rowHeightDic setObject:HEI forKey:KEYID];
        
        
    }
}

将各行高度返回到tableVIEW中

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int s=[indexPath section];
    if(s==0)
    {
       // NSInteger row= [indexPath row];
        return 40;
    }
    if(s==1)
    {
    if(hasreplay<=1)
    {
        return  40;
    }
        NSInteger row= [indexPath row];
        NSString *rowindex=[NSString stringWithFormat:@"%d",row ];
        NSString *height=[NSString stringWithFormat:@"%@",[rowHeightDic objectForKey:rowindex]];
        
        CGFloat rowhe=[height floatValue ];
        return rowhe;
        
        }
        
   
}




- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellWithIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithIdentifier];
        
        UILabel *titlecontentt=[[UILabel alloc]initWithFrame:CGRectMake(10, 0, 300, 20)];//cell里面的三个控件 设置的时候可以选择具体坐标
        titlecontentt.tag=150;
        // titleUnit.font=[UIFont fontWithName:@"Arial" size:12];
        titlecontentt.font=[UIFont systemFontOfSize:12];
        
        //  titleUnit.font=[UIFont systemFontOfSize:sysconfig.table_common_cell_desc_size];
        titlecontentt.lineBreakMode = UILineBreakModeWordWrap;//自动换行
        
        [titlecontentt setTextColor:[UIColor grayColor]];
        titlecontentt.numberOfLines = 0;
        //[titleUnit setVerticalAlignment:VerticalAlignmentTop];
        titlecontentt.backgroundColor=[UIColor clearColor];
        [cell.contentView addSubview:titlecontentt];

        
        
        UILabel *titleUnit=[[UILabel alloc]initWithFrame:CGRectMake(30, 40, 120, 20)];
        titleUnit.tag=100;
        // titleUnit.font=[UIFont fontWithName:@"Arial" size:12];
        titleUnit.font=[UIFont systemFontOfSize:12];
        
        //  titleUnit.font=[UIFont systemFontOfSize:sysconfig.table_common_cell_desc_size];
        titleUnit.lineBreakMode = UILineBreakModeWordWrap|UILineBreakModeTailTruncation;
        
        [titleUnit setTextColor:[UIColor grayColor]];
        titleUnit.numberOfLines = 1;
        //[titleUnit setVerticalAlignment:VerticalAlignmentTop];
        titleUnit.backgroundColor=[UIColor clearColor];
        
        [cell.contentView addSubview:titleUnit];
        
        UILabel *titleuserid=[[UILabel alloc]initWithFrame:CGRectMake(200, 40, 120, 20)];
        titleuserid.tag=180;
        // titleUnit.font=[UIFont fontWithName:@"Arial" size:12];
        titleuserid.font=[UIFont systemFontOfSize:12];
        
        //  titleUnit.font=[UIFont systemFontOfSize:sysconfig.table_common_cell_desc_size];
        titleuserid.lineBreakMode = UILineBreakModeWordWrap|UILineBreakModeTailTruncation;
        
        [titleuserid setTextColor:[UIColor grayColor]];
        titleuserid.numberOfLines = 1;
        //[titleUnit setVerticalAlignment:VerticalAlignmentTop];
        titleuserid.backgroundColor=[UIColor clearColor];
        [cell.contentView addSubview:titleuserid];

    }
    
     int s=[indexPath section];
    if(s==0)
    {
        
    NSUInteger row = [indexPath row];
        if(row==0)
        {
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];//初始化button,选择button类型
            
            btn.frame = CGRectMake(200, 10, 90, 35);//大小和位置
            
            [btn setTitle:@"反馈图片" forState:UIControlStateNormal];//正常状况下button显示的标题
            
            
            [btn addTarget:self action:@selector(imagepress:) forControlEvents:UIControlEventTouchUpInside];
            [cell.contentView addSubview:btn];
        }
    ///////显示词汇IDAllfeedbackArray
    NSMutableDictionary * MYfeed=[feedbackDic objectForKey:@"myfeedback"];
       // Userfeedback *myfeedbck=[[Userfeedback alloc] init];
    NSString *content=[NSString stringWithFormat:@"%@",[MYfeed objectForKey:@"content"] ];
 
   
    
    NSString *DATE=[NSString stringWithFormat:@"%@",[MYfeed objectForKey:@"date"] ];
    
        UILabel *titleUnit= (UILabel *)[cell.contentView viewWithTag:100];
        titleUnit.text = DATE;
        
        UILabel *titlecontent= (UILabel *)[cell.contentView viewWithTag:150];
        
    titlecontent.text = content;
     
    }
    
    if(s==1)
    {
        if(hasreplay>1)
        {
        NSUInteger row = [indexPath row];
        
         NSMutableArray * MYfeed=[[feedbackDic objectForKey:@"detail"]objectForKey:@"detaillist" ];
        NSMutableDictionary *detail=[MYfeed objectAtIndex:row];
        NSString *content=[NSString stringWithFormat:@"%@",[detail objectForKey:@"content"] ];
       
        UILabel *titlecontent= (UILabel *)[cell.contentView viewWithTag:150];//三个控件具体赋值时就可以根据从存取高度字典rowHeightDic里读出的高度数据进行具体的动态调整
            NSString *rowindex=[NSString stringWithFormat:@"%d",row ];
            CGFloat hei=[[NSString stringWithFormat:@"%@",[rowHeightDic objectForKey:rowindex]] floatValue];
       
            [titlecontent setFrame:CGRectMake(titlecontent.frame.origin.x, titlecontent.frame.origin.y,  titlecontent.frame.size.width, hei)];//三个控件具体赋值时就可以根据从存取高度字典rowHeightDic里读出的高度数据进行具体的动态调整
        titlecontent.text = content;
        
        NSString *DATE=[NSString stringWithFormat:@"%@",[detail objectForKey:@"date"] ];
        
        UILabel *titleUnit= (UILabel *)[cell.contentView viewWithTag:100];
            [titleUnit setFrame:CGRectMake(titleUnit.frame.origin.x, hei-60,  titleUnit.frame.size.width, titleUnit.frame.size.height)];//三个控件具体赋值时就可以根据从存取高度字典rowHeightDic里读出的高度数据进行具体的动态调整
        titleUnit.text = DATE;
            
            
            
            NSString *user=[NSString stringWithFormat:@"%@",[detail objectForKey:@"user"] ];
            
            UILabel *titleuser= (UILabel *)[cell.contentView viewWithTag:180];
           [titleuser setFrame:CGRectMake(titleuser.frame.origin.x,hei-60,  titleuser.frame.size.width, titleuser.frame.size.height)];//三个控件具体赋值时就可以根据从存取高度字典rowHeightDic里读出的高度数据进行具体的动态调整
            titleuser.text = user;
        }
        
        else
            
        {
            cell.textLabel.text=@"暂时还未处理";
            cell.textLabel.font=[UIFont systemFontOfSize:12];
            [cell setTextColor:[UIColor grayColor]];
        }

    }
    
    // cell.accessoryType = UITableViewCellSelectionStyleBlue;
    
    return cell;
}

注意:在cell外设置控件的调整后纵坐标值时尽量用从字典中读到的值减去一个具体值,如果加入原来纵坐标.frame.origin.y的话,当tableview上下滑动时控件会消失。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值