【问题标题】:Expanding UITextView inside UITableViewCell在 UITableViewCell 内展开 UITextView
【发布时间】:2014-02-19 16:32:58
【问题描述】:

关于 SO 的问题有十几个类似的问题,但似乎没有就最佳方式达成共识。此外,我还没有找到任何适合我的解决方案。我的自定义 UITableViewCell 的不同之处在于我有两个标签,其中一个在它自己的视图中,还有一个文本视图。这三个都应该扩展到它们的内容。

我想知道是不是我的约束设置不正确,但我不确定我会调整什么。

这是我在 IB 的牢房。

内容视图是浅红色的,顶部的额外视图是白色的,里面有一个标签。

当文本更改时,我保存文本并更新tableView

-(void)textViewDidChange:(UITextView *)textView
{
    NSLog(@"row: %i", textView.tag);
    [self.textStrings setObject:textView.text atIndexedSubscript:textView.tag];
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

对于tableView:heightForRowAtIndexPath: 方法,我使用缓存的高度值(选定行除外)。在这种情况下,我将创建一个新单元格,对其进行配置,并使用systemLayoutSizeFittingSize: 获取高度。这似乎是最常见的solution

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // use cached height if there is one (and it isn't the selected row)
    if ([self.selectedRow integerValue] != indexPath.row && indexPath.row < [self.rowHeights count]){
        return [[self.rowHeights objectAtIndex:indexPath.row] floatValue];
    }

    static NSString *CellIdentifier = @"RMTextViewCell";
    RMTextViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    [self configureCell:cell forIndexPath:indexPath];

    [cell layoutIfNeeded];

    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    height += 1; // add 1 for border

    NSNumber *h = @(height);
    [self.rowHeights setObject:h atIndexedSubscript:indexPath.row];

    return height;
}

textView 确实展开了,但是当它进入多行时,顶部标签开始被剪裁。在某些版本中,当文本更改时,我已经让 textView 开始剪切/扩展。似乎自动布局不确定如何正确计算单元格的高度。

有什么想法吗?

这是我的Github project,里面有一些实验。重要文件是ViewControllers/RMTextViewTableViewControllerCell/RMTextViewCell。如果您运行它,请查看“带文本的动态单元格”。

【问题讨论】:

    标签: ios objective-c uitableview


    【解决方案1】:

    似乎这可能是一个 iOS 错误,因为我希望 UITextView 的高度将作为 UILabel 包含在它位于单元格的 contentView 中并且我们使用 systemLayoutSizeFittingSize 时。无论如何,正如 user501836 所说,您可以手动计算 textView 的高度。然后,您需要将其添加到为您的 contentView 计算的高度。这是我如何计算 tableView 中的单元格高度的示例:heightForRowAtIndexPath:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
    
        CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    
        CGSize textViewSize = [[cell textView] sizeThatFits:CGSizeMake([[cell textView] frame].size.width, FLT_MAX)];
    
        height += textViewSize.height;
    
        return height;
    
    }
    

    【讨论】:

      【解决方案2】:

      我也有同样的问题。 UITableViewCell 中的UILabel 计算正确,但UITableViewCell 中的UITextView 计算不正确。

      所以只能手动计算高度:

      CGSize textViewSize = [cell.textView sizeThatFits:CGSizeMake(cell.textView.frame.size.width, FLT_MAX)];
      

      【讨论】:

      • 如何添加单元格的其余部分,因为标签也可以是多行?
      • 终于想通了。我将在未来的某个时候发布更多关于我如何进行计算的细节。谢谢。
      • 你能发布这些细节 RyanJM 吗?我有同样的问题
      • 同上,同样的问题,如果你能发布你的解决方案,那就太好了!
      【解决方案3】:

      我一直在寻找一种适用于 iOS7 和 iOS8 的解决方案。基于上面jobb的回答,我添加了一些代码来使用UITextView.contextSize与UITextView.frame.size处理旋转。

      我还发现在 xCode 6 中似乎 systemLayoutSizeFittingSize 正在考虑 UITextView 的 textContainerInsets。所以我发现在向 systemLayoutSizeFittingSize 添加额外高度之前将它们设置为零可以更好地设置间距。

      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      {
          // Get the cell once and save it in an NSDictionary. Thisupports cases with multiple cells types.
          CCTextViewCell *sizingCell = [self.offscreenCells objectForKey:CellIdentifier];
          if (!sizingCell) {
              sizingCell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
              [self.offscreenCells setObject:sizingCell forKey:CellIdentifier];
          }
      
          [self populateCellViewWithData:sizingCell atIndexPath:indexPath];
      
          sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(sizingCell.bounds));
          [sizingCell setNeedsLayout];
          [sizingCell layoutIfNeeded];
      
          // UITextViews don't autosize well with systemLayoutSizeFittingSize.
          // We need to add the sum of the heights of the UITextViews without its textContainerInsets to the height.
          // We also need to set the textContainerInsets to zero so that systemLayoutSizeFittingSize give the right number.
          // So we do this first.
          CGFloat additionalUITextViewsHeight = 0;
          for (UIView *subVw in sizingCell.contentView.subviews) {
              if ([subVw isKindOfClass:[UITextView class]]) {
                  UITextView *subTextView = (UITextView*) subVw;
      
                  subTextView.textContainerInset = UIEdgeInsetsZero;
                  CGSize textViewSize = [subTextView sizeThatFits:CGSizeMake(subTextView.contentSize.width, FLT_MAX)];
                  additionalUITextViewsHeight += textViewSize.height;
              }
          }
      
          CGFloat height = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + additionalUITextViewsHeight;
      
          return height;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-18
        • 2013-01-02
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        相关资源
        最近更新 更多