【问题标题】:Trying to calculate frame size of UILabel based on the amount of text for subview of cell尝试根据单元格子视图的文本量计算 UILabel 的帧大小
【发布时间】:2011-09-01 10:56:22
【问题描述】:

下面的代码具有确定 UILabel 帧大小的代码,我认为它确实有效,但是当我将它放在 UItable 的 rowAtIndexPath 中时,我得到了不稳定的结果。

也许,我不完全理解reuseIdentifier 是如何或做什么的,但是我只在单元格为nil 时放置了代码来计算框架。发生的情况是仅计算前三个单元格的高度,然后按顺序重复其余单元格的高度。例如,单元格一的高度用于单元格四的高度。

也许有人可以指出我应该如何设置计算的正确方向。

谢谢!

if(cell == nil){

    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                reuseIdentifier:DisclosureButtonCellIdentifier] autorelease];

    //start adding custom subviews to the table cell


    //addSubview for Description
UILabel *descValue = [[UILabel alloc] init];
    NSString *descString = rowData.summary;
    CGSize maximumSize = CGSizeMake(185, 130);
    UIFont *descFont = [UIFont fontWithName:@"HelveticaNeue" size:12];
    CGSize descStringSize = [descString sizeWithFont:descFont 
                                   constrainedToSize:maximumSize 
                                       lineBreakMode:descValue.lineBreakMode];
    CGRect descFrame = CGRectMake(125, 60, 185, descStringSize.height);
    descValue.frame = descFrame;

    descValue.backgroundColor = [UIColor redColor];
    descValue.font = descFont;
    descValue.tag = kDescriptionValueTag;
    descValue.lineBreakMode = UILineBreakModeWordWrap;
    descValue.numberOfLines = 0;

    [cell.contentView addSubview:descValue];
    [descValue release];
}


UILabel *desc = (UILabel *)[cell.contentView viewWithTag:kDescriptionValueTag];
    desc.text = rowData.summary;

【问题讨论】:

    标签: iphone objective-c ios cocoa-touch


    【解决方案1】:

    使用 NSString UIKit Additions,您可以使用特定字体获取字符串的宽度:

    [myString sizeWithFont:myFont];
    

    Additions 集中还有其他几个函数可以帮助确定一段文本的大小、不同的布局选项、单行和多行文本等。

    reuseIdentifier 的目的是让您重用一个单元格(在特定位置具有特定子视图),而无需设备花费执行时间来完成所有布局。在处理器速度慢得多的 iPhone 1 时代肯定更有用。在您更熟悉重用标识符之前,我建议您在每次调用该函数时创建一个新单元格。

    每次操作系统调用你的 cellForRowAtIndexPath 时,你都需要正确填写内容。应设置任何需要根据行调整大小或更改的内容。

    【讨论】:

      【解决方案2】:

      坦率地说,我没有尝试完全理解您的代码。这几乎是不可能的,特别是因为你用括号关闭方法而不返回任何东西,但我假设你指的是cellForRowAtIndexPath,需要返回一个UITableViewCell 对象。

      显然我们只查看了代码的一部分。

      但是,正确布局单元格并不是全部任务。您需要告诉表格每个单元格的高度。 您可能想要实施

      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      

      为那个任务。如果像元高度不同,该方法很好。 如果单元格高度与标准不同,但在不同单元格之间没有变化,则设置 tableView 的 rowHeight 属性就足够了。

      我认为在您的情况下,方法 heightForRowAtIndexPath 的实现是强制性的。

      顺便说一句,您可能希望查看 UITableCellView 的子类化并在您的子类中实现 layoutSubviews 方法。

      【讨论】:

      • 谢谢。使用 layoutSubviews 的原因是什么?是的,它只是代码的一部分,其余的是基本的 tableview 代码。单元格高度是固定的。我想计算高度,因为下面会有其他 uilabels,我希望它们在下面正确对齐。我只是想知道为什么 cell==nil 只执行了 3 次,并且没有计算或运行其余的单元格。
      • 好吧,亚当,这有点猜测,因为您没有显示所有代码。假设“基本表格视图”代码意味着您在代码之前执行了 UITableViewCell ,那么请了解表格单元格的重用机制。如果一个单元格(连同它的所有资源,如子视图、图像)从屏幕上消失,则可以重新使用它。如果您的视图足够高以至于只能显示 3 个单元格,则对于第 4 个单元格,第一个(现在不可见)将被重用。这意味着您不会输入代码的 cell==nil 部分。您当然可以将部分代码移出 if 子句,...
      • ... 或者您将所有代码移到 UITableViewCell 的子类中。其中一些代码实际上可能会转到单元格的 initWithStyle 方法,而其中一些应该移至 layoutSubViews。但是,我确信您可以在 cellForRowAtIndexPath 中处理所有这些问题,但这并不那么性感。 :)
      • 只需要了解你的 cell==nil 分支只会在分配新单元时执行,而不是在重用现有单元时执行。一次从不显示超过 3 个单元格的表格 - 因为它们的大小 - 不需要分配超过 3 个单元格对象。
      【解决方案3】:

      您没有展示所有代码,但通常是为了实现 tableView:cellForRowAtIndexPath: 您从以下内容开始:

      -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {
          // get a cell from the queue of reusable cells, if any
          UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: DisclosureButtonCellIdentifier];
      
          if (cell == nil) {
              // No cell to reuse, need to create a new one
              cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:DisclosureButtonCellIdentifier] autorelease];  
      
              // add cell subviews here      
          }
      
          // fill in cell content and resize subviews here
          ...
      
          return cell;
      }
      

      一旦您创建了 3 个(在您的情况下)单元格,它们就会在表格滚动时重复使用,因此您不必继续创建单元格。对 dequeueReusableCellWithIdentifier 的调用将返回先前创建的单元格之一,如果它不再使用(它从顶部或底部滚动)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-08
        • 1970-01-01
        • 2015-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多