调整自定义UITableViewCell在该单元格中的UITextView的高度和高度(存在其他UI元素)

时间:2012-11-23 05:50:05

标签: ios dynamic uitableview height uitextview

我有一个自定义表格单元格,其中包含3个标签,一个按钮和一个UITextView。

UITextView的文本仅在运行时已知,因为它是从服务器中提取的数据。

我正在尝试根据我放入UITextView的文本,将我的UITextView和自定义表格单元格调整到正确的高度。

UITextView的文本设置在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法。

在这里,我正在尝试使用以下内容调整UITextView(bodyTextView)的大小。

CGSize stringSize = [cell.bodyTextView.text sizeWithFont:cell.bodyTextView.font constrainedToSize:CGSizeMake(cell.bodyTextView.bounds.size.width, 9999) lineBreakMode:NSLineBreakByWordWrapping];

[cell.bodyTextView setText:threadMessage.body];

CGRect bodyFrame = cell.bodyTextView.frame;

bodyFrame.size = cell.bodyTextView.contentSize;

[cell.bodyTextView setFrame:bodyFrame];

或多或少似乎工作正常,或者我的UIButton没有向下移动到它应该的位置,即使它在我的UITextView底部有一个“Top Space To”约束。我会认为它会自动移动。但是我可以以编程方式将其移动到适当的位置,这不是什么大问题。

下一段代码确实将tableViewCell的大小调整到适当的高度以适应标签和UITextView,但底部的按钮没有足够的空间。 接下来,我计算单元格的高度并使用以下内容返回...

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath
{
    CGSize stringSize = [threadMessage.body sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(280, 9999) lineBreakMode:NSLineBreakByWordWrapping];

    float oldHeight = 28;
    float newHeight = stringSize.height;

    return tableView.rowHeight - oldHeight + newHeight;
}

正如您所看到的,我在UITextView高度与新高度之间的高度差异很大。我试图以编程方式获得oldHeight,但我在数千人中获得了疯狂的价值。

最大的问题是,当视图首次显示时,行的大小,或多或少都是正确的。但是UITextView的大小并不大。如果我滚动将其移出屏幕然后向后滚动,则UITextView的大小正确。但是,如果我将其滚动并再次返回屏幕,它又会重新调整为一行。

我觉得我有一个鸡肉或鸡蛋的东西正在进行,无法解决这个问题。

我希望得出的两个主要问题是:

1)如何让UITextView从一开始就正确调整大小并保持这种状态,无论在屏幕上滚动还是在屏幕上?

2)如何让我的自定义TableCellView适当调整大小以包含按钮的高度?

我希望这一切都有道理,我已经提供了足够的细节。让我知道任何问题。

非常感谢任何建议。谢谢!

此致

彼得

3 个答案:

答案 0 :(得分:1)

好的,我终于找到了问题。我想我会发布我的解决方案,以防其他人遇到这种情况,因为今天我的大脑扭了好几个小时。

我认为这个问题可能与我使用iOS 6 SDK的项目有关。我下载了iOS 5模拟器并尝试在其上运行我的应用程序。它在启动后立即出错。 NSLayoutInconsitencyException(或类似的东西)。经过一些在线搜索后,我发现iOS 5与iOS 6中的设置不兼容。

此设置为“User Autolayout”,并在我的故事板文件中进行了检查。要找到它,请选择您的故事板文件,然后选择右侧的File Inspector(Command-Option-1)。在Interface Builder Document部分下,您将看到“Use Autolayout”的复选框。取消选中此项,事情开始变得更好。每次我在屏幕上和屏幕上滚动单元格时,我的UITextView不再被调整为一行并返回到完整长度。

然而,我仍然有一个问题,细胞不是正确的高度。现在我已经解决了Autolayout问题(你不会相信我到处都注释掉所有已经注释掉的试错代码:)。

在cellforRowAtIndexPath函数中,您需要将UITextView的文本设置为您想要的文本,然后简单地获取它的contentSize,然后调整UITextView的框架...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCellIdentifier"];

    [cell.bodyTextView setText:myText];

    CGRect bodyFrame = cell.bodyTextView.frame;
    bodyFrame.size = cell.bodyTextView.contentSize;
    [cell.bodyTextView setFrame:bodyFrame];

    ... Whatever else you need to do here ...
}

然后在heightForRowAtIndexPath中我发现再次获取一个单元格并设置文本我能够获得正确的大小差异,因此返回适当的大小。通过使用大小差异,它允许您在表格单元格中拥有的任何其他UI元素。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCellIdentifier"]; 

    float oldHeight = cell.bodyTextView.frame.size.height;

    cell.bodyTextView.text = threadMessage.body;

    CGRect bodyFrame = cell.bodyTextView.frame;
    bodyFrame.size = cell.bodyTextView.contentSize;

    float newHeight = cell.bodyTextView.contentSize.height;

    return tableView.rowHeight - oldHeight + newHeight;
}

我希望这有助于将来的某些人。如果任何问题没有意义,请随时问我任何问题。感谢Mohit试图帮助我。非常感谢。

答案 1 :(得分:0)

Etep,试试这个...首先你要关闭单元格和按钮的调整大小/方向属性,之后你可以根据你到达的文本制作正确的文本视图尺寸,这样你就可以了。重新计算行高,而不是使用获取文本大小,你需要什么来获得文本视图的正确高度......并且休息很好。(在'cellForRowAtIndexPath'中,你应该使用可重用的单元格,或者说将你的代码放在if(cell == nil){})

答案 2 :(得分:0)

在旋转时自动调整自定义单元格时,我也遇到了同样的问题。战斗结束后,我得到了解决方案作为authorize cell.contentView,因为我将我的视图作为子视图添加到cell.contentview中。

我使用了以下代码,我的代码运行正常:)

cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;