UITableView - 由单元本身控制的动态单元格高度 [英] UITableView - dynamic cell height controlled by cell itself

查看:143
本文介绍了UITableView - 由单元本身控制的动态单元格高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下设置:UITableView与自定义UITableViewCell实现。在每个单元格中,我有一个UILabel和一个UIButton。当表首次显示时,在每个单元格中,UILabel的行数设置为1,所有单元格具有固定高度(在我的情况下为60像素)。当单元格中的按钮被点击时,UILabel的行数被设置为0,并且打开了单词换行,有效地扩展了表格单元格。



现在,问题是只有UITableViewCell的实现才能知道标签是否被扩展 - 因此,单元格高度应该是什么。但是,所有者文件是表的数据源。



我无法得到可能会围绕如何设置。任何想法都不胜感激。



更新这里是我的代码摘录



定制的UITableViewCell实现:

   - (float)requiredHeight 
{
if(isFull)
{
CGSize labelSize = [LblTitle.text sizeWithFont:[LblContent font]
constrainedToSize:CGSizeMake(300.0f,300.0f)
lineBreakMode:UILineBreakModeTailTruncation];
return 42.0f + labelSize.height;
}
else
{
返回60.0f;
}
}

在所有者文件(UITableViewDelegate)中:

   - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath :( NSIndexPath *)indexPath 
{
OOCommentCell *单元格=(OOCommentCell *)[tableView cellForRowAtIndexPath:indexPath];
return [cell requiredHeight];
}

然而,这个结果是无限循环或BAD_ACCESS_EXCEPTION中的。

解决方案

可以,经过一些挣扎,这里是我最终的结果,哪种作品。


  1. 我创建了一个简单的类来包含与一个单元格相关的信息:




  @interface CommentInfo:NSObject 
{
int ID;
NSString * Name;
NSString * Date;
NSString *内容;
BOOL IsFull;
float Height;
}

@property(readonly)int ID;
@property(readonly)NSString * Name;
@property(readonly)NSString * Date;
@property(只读)NSString *内容;
@property(readwrite,assign)float Height;
@property(readwrite,assign)BOOL IsFull; (NSString *)_ name withDate:(NSString *)_ date withText:(NSString *)_ text;

- (id)initWithID:(int)_id withName:

@end


不要担心所有的属性太多 - 最重要的一个是 Height


  1. 在我的控制器(也是表视图的委托)中,我将数据作为 NSMutableArray 指向类型为


  2. cellForRowAtIndexPath 中,我得到相应的指针并传递它在构造期间的自定义单元实现,存储在哪里。我还将 self 设置为单元的代表。


  3. 在自定义单元格实现中,当我需要扩展/更改高度,我更新 CommentInfo 对象中的 Height 属性,并在代理中调用一个方法更新显示。


  4. 当调用此 updateDisplay 方法时,我简单地执行以下操作: / p>





  [CommentsTable beginUpdates]; 
[CommentsTable endUpdates];





  1. heightForRowAtIndexPath 方法,我检索到相应的指向 CommentInfo 并读取 Height 属性。由于控制器和单元格之间的指针是相同的,所以对这两个类都可以看到对此属性的任何更改。


I have the following setup: UITableView with custom UITableViewCell implementation. In each cell I have a UILabel and a UIButton. When the table is first displayed, in each of the cells, the UILabel has the number of lines set to 1 and all cells have fixed height (60 px in my case). When the button in the cell is tapped, then the UILabel's number of lines is set to 0 and word wrap is turned on, effectively expanding the table cell.

Now, the issue is that only the implementation of UITableViewCell knows whether the label is expanded or not - and thus what the cell height should be. However the owner file is the table's datasource.

I can't get may head around how to set this up. Any ideas are appreciated.

Update here are extracts from my code

In the custom UITableViewCell implementation:

- (float)requiredHeight
{
    if(isFull)
    {
        CGSize labelSize = [LblTitle.text sizeWithFont: [LblContent font]
                                     constrainedToSize: CGSizeMake(300.0f, 300.0f) 
                                         lineBreakMode: UILineBreakModeTailTruncation];
        return 42.0f + labelSize.height;
    }
    else
    {
        return 60.0f;
    }
}

In owner file (UITableViewDelegate):

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    OOCommentCell *cell = (OOCommentCell*)[tableView cellForRowAtIndexPath:indexPath];
    return [cell requiredHeight];
}

However this results randomly in an infinite loop or in BAD_ACCESS_EXCEPTION.

解决方案

OK, after some struggling, here's what I ended up with, which kind of works.

  1. I created a simple class to contain information related to one cell:

@interface CommentInfo : NSObject
{
    int ID;
    NSString *Name;
    NSString *Date;
    NSString *Content;
    BOOL IsFull;
    float Height;
}

@property (readonly) int ID;
@property (readonly) NSString *Name;
@property (readonly) NSString *Date;
@property (readonly) NSString *Content;
@property (readwrite, assign) float Height;
@property (readwrite, assign) BOOL IsFull;

- (id)initWithID:(int)_id withName:(NSString *)_name withDate:(NSString *)_date withText:(NSString *)_text;

@end

Don't worry too much about all the properties - the most important one is the Height.

  1. In my controller (which is also the delegate for the table view), I keep the data as an NSMutableArray of pointers to objects of type CommentInfo.

  2. In cellForRowAtIndexPath I get the corresponding pointer and pass it to the custom cell implementation during construction, where it is stored. I also set self as a delegate to the cell.

  3. In the custom cell implementation, when I need to expand/change the height, I update the Height property in the CommentInfo object and call a method in the delegate to update the display.

  4. When this updateDisplay method is called, I simple do the following:

[CommentsTable beginUpdates];
[CommentsTable endUpdates];

  1. In heightForRowAtIndexPath method, I retrieve the corresponding pointer to CommentInfo and read the Height property. As the pointer is the same between the controller and the cell, any changes to this property will be visible in both classes.

Job done.

这篇关于UITableView - 由单元本身控制的动态单元格高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆