UITableViewCell 中的 UITextView 平滑自动调整大小
Posted
技术标签:
【中文标题】UITableViewCell 中的 UITextView 平滑自动调整大小【英文标题】:UITextView in a UITableViewCell smooth auto-resize 【发布时间】:2010-09-20 08:29:00 【问题描述】:我在 UITableViewCell 内容视图中有一个 UITextView 并允许单元格自动调整大小,以便完全显示输入的文本 - 当您输入“注释”时,我想要完成的是一个自动调整大小的单元格,就像本机 ios4 联系人应用程序一样对于联系人 - 即当 textView 的 contentSize 发生变化时 - 我调用 reloadRowsAtIndexPaths 并在委托的 heightForRowAtIndexPath 中为行提供新高度 - 这可以完成工作,但是它不像联系人的应用程序那样好和流畅 - 我几乎可以肯定 Apple在该应用程序中使用了一些未记录的技巧来使单元格的 contentView 扩展平滑和动画,而无需调用 reloadRowsAtIndexPaths。我的问题是你会建议如何实现这样的功能?我希望我在解释中没有遗漏任何细节。
【问题讨论】:
你试过使用 UIView 的动画吗?我从来没有用过它们,但这可能会奏效。 是的,我已经为内部内容尝试了一些 UIView 动画,它有点使过程更顺畅,但我想知道是否有办法不使用 reloadRowsAtIndexPaths,似乎没有公开的方法。 【参考方案1】:试试下面的代码,它会有所帮助。您不必使用任何重新加载函数,例如 reloadRowsAtIndexPaths。
// 文本视图委托
- (void)textViewDidChange:(UITextView *)textView
if (contentView.contentSize.height > contentRowHeight)
contentRowHeight = contentView.contentSize.height;
[theTableView beginUpdates];
[theTableView endUpdates];
[contentView setFrame:CGRectMake(0, 0, 300.0, contentView.contentSize.height)];
// 表视图委托
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
CGFloat height;
if (indexPath.row == 0)
height = kTitleRowHeight;
else
height = contentRowHeight;
return height;
【讨论】:
这是 UITableViewCell 的属性。在此属性中添加了 UITextView。 [cell.contentView addSubview:textView]; 我在我的应用程序中使用了这个解决方案,它在 iPhone 上可以 100% 运行,但在 iPad 上却不行:当用户键入多行文本时,UITableViewCell
应该会变高,但UITextView
实际上会向上 移动,因此第一行文本位于UITableViewCell
的顶部上方——并且被隐藏了。关于如何在 iPad 上解决这个问题的任何想法?
PS 我已经在***.com/questions/4015557/…发布了我的代码
@Jason:我的 iPad 应用程序按照您的描述工作,直到我将 contentView setFrame:... 消息放入其中。确保它在那里。【参考方案2】:
我找到了解决这个问题的最佳方法。
首先,当然,您需要创建 UITextView 并将其添加到单元格的 contentView。我创建了一个名为“cellTextView”的 UITextView 实例变量这是我使用的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
if (!cellTextView)
cellTextView = [[UITextView alloc] initWithFrame:CGRectMake(5.0, 5.0, cell.bounds.size.width - 30.0, cell.bounds.size.height - 10.0)]; // I use these x and y values plus the height value for padding purposes.
[cellTextView setBackgroundColor:[UIColor clearColor]];
[cellTextView setScrollEnabled:FALSE];
[cellTextView setFont:[UIFont boldSystemFontOfSize:13.0]];
[cellTextView setDelegate:self];
[cellTextView setTextColor:[UIColor blackColor]];
[cellTextView setContentInset:UIEdgeInsetsZero];
[cell.contentView addSubview:cellTextView];
return cell;
然后,创建一个名为 numberOfLines 的 int 变量,并在您的 init 方法中将该变量设置为 1。之后,在您的 textViewDelegate 的 textViewDidChange 方法中,使用以下代码:
- (void)textViewDidChange:(UITextView *)textView
numberOfLines = (textView.contentSize.height / textView.font.lineHeight) - 1;
float height = 44.0;
height += (textView.font.lineHeight * (numberOfLines - 1));
CGRect textViewFrame = [textView frame];
textViewFrame.size.height = height - 10.0; //The 10 value is to retrieve the same height padding I inputed earlier when I initialized the UITextView
[textView setFrame:textViewFrame];
[self.tableView beginUpdates];
[self.tableView endUpdates];
[cellTextView setContentInset:UIEdgeInsetsZero];
最后,将此代码粘贴到您的 heightForRowAtIndexPath 方法中:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
float height = 44.0;
if (cellTextView)
height += (cellTextView.font.lineHeight * (numberOfLines - 1));
return height;
【讨论】:
是的,这很好用 +1。此外,通过将 numberOfLines 存储在 index = indexPath.row 处的 NSArray 中,并将 textView.tag 设置在 indexPath.row 中,从而使许多单元格中的多个 UITextviews 随每个单元格中的文本大小而变化。 谢谢!一个简单的解决方法是找到一种不同的方法来确定要调整哪个 textView 的大小。这段代码被定制为每个单元格使用一个 textView。 @MarkRamotowski 如果可能的话,你能用代码详细说明一下吗? 好吧,让我重新考虑一下我在这里做了什么:因此,对于每个单元格中的每个 textView,在 NSArray 的每个元素中都有一个不同的“numberOfLines”整数变量。所以定义你的数组(让我们说两个不同的 uitableviewcells 中的两个 uitextviews)@[@numberOfLines1,@numberOfLines2];。现在您可以访问每个不同的变量并根据您所在单元格的 indexPath.row 更改其值。 这取决于您在 tableView 中是否有多个部分,如果有,那么我建议为每个部分使用单独的数组,如果没有,那么一个数组就足够了。您需要一种方法来根据单元格的动态数量增加和减少数组,但只要您的数组是动态的,每个单元格由数组中的有序值表示,您应该没问题。然后通过返回 [yourArray[indexPath.row] intValue]; 修改您的高度(使用 heightForRowAtIndexPath)以上是关于UITableViewCell 中的 UITextView 平滑自动调整大小的主要内容,如果未能解决你的问题,请参考以下文章
从 UIText 字段的用户输入更改 UIView 框架的高度和宽度
如何从 UITextfields UIMenuController 中删除不需要的 UIMenuItems?