【问题标题】:Calculate cell height based on cell's text in iOS 7在 iOS 7 中根据单元格的文本计算单元格高度
【发布时间】:2013-11-25 20:59:31
【问题描述】:

有许多使用“sizeWithFont”或类似内容的解决方案,而这恰好在 iOS 7 中已被弃用。

这是迄今为止我拼凑的一些代码。高度发生变化,但完全不准确:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

// Configure the cell...
cell.textLabel.text = "The Cell's Text!";
cell.textLabel.numberOfLines = 0;
[cell.textLabel setLineBreakMode:NSLineBreakByWordWrapping];
[cell.textLabel sizeToFit];

return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBounds.size;

NSAttributedString *aString = [[NSAttributedString alloc] initWithString:"The Cell's Text!"];
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:aString];
CGSize size = [calculationView sizeThatFits:CGSizeMake(screenSize.width, FLT_MAX)];
return size.height;
}

再举一个例子,这是一个类似的答案:https://stackoverflow.com/a/9828777/693121 虽然正如我之前所说,这使用了已弃用的代码。

【问题讨论】:

    标签: ios objective-c uitableview ios7


    【解决方案1】:

    您应该使用文档中提到的方法来替换旧的方法——boundingRectWithSize:options:attributes:context:。这是我认为应该可行的示例(无论如何它都适用于多行标签)。

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSStringDrawingContext *ctx = [NSStringDrawingContext new];
        NSAttributedString *aString = [[NSAttributedString alloc] initWithString:@"The Cell's Text!"];
        UITextView *calculationView = [[UITextView alloc] init];
        [calculationView setAttributedText:aString];
        CGRect textRect = [calculationView.text boundingRectWithSize:self.view.frame.size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:calculationView.font} context:ctx];
            return textRect.size.height;
      }
    

    这假设您希望文本视图的大小与 self.view 相同。如果没有,您应该为您的文本视图使用 initWithFrame,并为 boundingRectWithSize: 参数传递calculationView.frame.size。

    【讨论】:

    • 出于某种原因,它总是返回 13.8 的高度?不管“aString”变量中有多少文本。
    • @Demasterpl,对不起,我在答案中使用了错误的选项参数,它应该是 NSStringDrawingUsesLineFragmentOrigin。我已经更正了我的答案。
    • 这似乎返回了一个可观的值,尽管有时即使高度很大,但它似乎仍然保持默认高度。此外,如果我删除了单元格属性(如 sizeToFit 和 setLineBreakMode),它似乎并没有什么不同。 :(
    • @Demasterpl,什么保持默认高度?单元格,还是文本视图?
    • 我有 NSStringDrawingUsesLineFragmentOrigin 在那里,我仍然得到 @Demasterpl 得到的 13.8。
    【解决方案2】:

    这是最简单的版本,iOS 7 完成了所有繁重的工作(仅适用于基于自动布局的 uitableviewcells):

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
       CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: @"Cell"];
    
       [self configureCell:cell];
    
       // edit: Need to call [cell layoutIfNeeded]; otherwise the layout changes wont be applied to the   cell
    
       [cell layoutIfNeeded];
    
    
       return [cell.contentView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize].height;
    }
    

    systemLayoutSizeFittingSize 重新评估自动布局约束并返回单元格的完美高度。简单吧?

    【讨论】:

    • 方法是什么[self configureCell:cell]; ?
    • 依赖于数据对象的单元格的基本设置(例如,设置标签)。有了它,我用内容“填充”单元格,因此自动布局可以自动确定所需的高度
    【解决方案3】:

    我从我的同事 (ANIRUDH) 那里得到它并且工作正常,可能会有所帮助:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    
    //Calculating height on base of length of text
        UIFont *font =  [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
        NSAttributedString *attributedText =
        [[NSAttributedString alloc]
         initWithString:YOURSTRING //[NSString string withformat:@"\n Yourstring"] \n for: number of lines require for static label in cell
         attributes:@
         {
         NSFontAttributeName: font
         }];
        CGRect rect = [attributedText boundingRectWithSize:(CGSize){CELL_CONTENT_WIDTH, CGFLOAT_MAX}
                                                   options:NSStringDrawingUsesLineFragmentOrigin
                                                   context:nil];
        CGSize size = rect.size;
    
        //  NSString *height = [NSString stringWithFormat: @"%.2f", ceilf(size.height)+22];
        return (ceilf(size.height)+22)*0.6; //change 0.6 to 0.9 according to the difference in required and extra calculted height, it works for me every time
    }
    

    【讨论】:

      【解决方案4】:
      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      {
          NSString *yourText = [[resultArray objectAtIndex:indexPath.row] valueForKey:@"review_text"];
          CGSize lblwidth = CGSizeMake(300, CGFLOAT_MAX);
          CGSize requiredSize = [yourText sizeWithFont:[UIFont fontWithName:@"CALIBRI" size:17] constrainedToSize:lblwidth lineBreakMode:NSLineBreakByWordWrapping];
          int calculatedHeight = requiredSize.height+50;
          return (float)calculatedHeight;
      }
      

      【讨论】:

        【解决方案5】:

        要获取字符串的大小,您应该使用- (CGSize)sizeWithAttributes:(NSDictionary *)attars

        因此,对于您的示例,您可以这样计算文本标签的高度:

        CGSize *cellSize = [cell.textLabel.text sizeWithAttributes:@{NSFontAttributeName:[cell.textLabel.font]}];
        

        CGSize *rowSize = [aString sizeWithAttributes:nil];
        

        【讨论】:

        • 这行不通。来自 Apple 的文档:“如果要在单行上使用指定的字体呈现,则返回字符串的大小。”如果您尝试根据多行标签更改单元格高度,这将没有用。
        猜你喜欢
        • 2013-01-28
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-05
        • 1970-01-01
        相关资源
        最近更新 更多