UITableView - 由单元格本身控制的动态单元格高度
Posted
技术标签:
【中文标题】UITableView - 由单元格本身控制的动态单元格高度【英文标题】:UITableView - dynamic cell height controlled by cell itself 【发布时间】:2012-01-24 00:10:55 【问题描述】:我有以下设置:具有自定义 UITableViewCell 实现的 UITableView。在每个单元格中,我都有一个 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
return 60.0f;
在所有者文件(UITableViewDelegate)中:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
OOCommentCell *cell = (OOCommentCell*)[tableView cellForRowAtIndexPath:indexPath];
return [cell requiredHeight];
但是,这会随机导致无限循环或 BAD_ACCESS_EXCEPTION。
【问题讨论】:
【参考方案1】:在您的表委托中实现方法UITableViewDelegate – tableView:heightForRowAtIndexPath:。如果您想在每个单元格的基础上定义高度,您可以通过在 tableView:heightForRowAtIndexPath 中调用您自己的 tableView:cellForRowAtIndexPath: 方法将此调用“转发”到单元格的类。
更新:在代码中实现。该错误是由调用 tableView:cellForRowAtIndexPath 的委托中的方法签名不正确引起的。
在自定义 UITableViewCell 实现中:
- (CGFloat)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;
在所有者文件(UITableViewDelegate)中:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
OOCommentCell *cell = (OOCommentCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
return [cell requiredHeight];
【讨论】:
我认为我没有遵循您的逻辑。我已经定义了heightForRowAtIndexPath
,在其中我尝试在 indexpath 中获取单元格,然后在其中调用一个方法以返回所需的路径,但这会导致 bad_access_exception。
基本上,表格是在询问 UITableViewDelegate,“X 行应该有多高?”通过方法 tableView:heightForRowAtIndexPath:。您应该返回所需高度(以像素为单位)的 CGFloat,而不是索引路径。
@JacobJinnings:您似乎误读了我的代码。对于“第 X 行应该有多高”,我试图获取第 X 行并询问它应该有多高 - 并返回该值。请仔细查看代码。【参考方案2】:
好的,经过一番挣扎,这就是我最终得到的,哪种有效。
-
我创建了一个简单的类来包含与一个单元格相关的信息:
@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
不要太担心所有属性 - 最重要的是Height
。
在我的控制器(也是表视图的委托)中,我将数据保存为 NSMutableArray
指针,指向 CommentInfo
类型的对象。
在cellForRowAtIndexPath
中,我得到了相应的指针,并在构造过程中将其传递给自定义单元实现,并存储在那里。我还将self
设置为单元格的代表。
在自定义单元格实现中,当我需要扩展/更改高度时,我会更新CommentInfo
对象中的Height
属性,并在委托中调用一个方法来更新显示。
当这个updateDisplay
方法被调用时,我简单的做如下:
[CommentsTable beginUpdates]; [CommentsTable endUpdates];
-
在
heightForRowAtIndexPath
方法中,我检索到CommentInfo
的相应指针并读取Height
属性。由于控制器和单元格之间的指针相同,因此对该属性的任何更改都将在两个类中可见。
工作完成。
【讨论】:
我在 UITableViewCell 中使用 UIWebView,因此在调用 heightForRowAtIndexPath 时它无法判断高度。我所做的是将单元格设置为 UIWebView 的委托,并在 webViewDidFinishLoad 方法中调用 [webView sizeToFit]; webView.hidden = 否; [tableViewController setRowHeight:webView.bounds.size.height forRowId:id];在 UITableViewController 的 setRowHeight 方法中,我调用了您提供的这两个方法: [tableView beginUpdates]; [tableView endUpdates];它有效。以上是关于UITableView - 由单元格本身控制的动态单元格高度的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 内 UITableView 的动态行高
如何更新动态生成的故事板中的自定义特定 UITableview 单元格?