IOS:具有自定义 uitableviewcell 的动态高度

Posted

技术标签:

【中文标题】IOS:具有自定义 uitableviewcell 的动态高度【英文标题】:IOS: dynamic height with a custom uitableviewcell 【发布时间】:2011-08-19 22:52:03 【问题描述】:

我是 ios 开发的新手,到目前为止这是我的问题。我能够通过委托“heightForRowAtIndexPath”动态计算自定义单元格的高度。所以在第一次加载时,一切都显示得很好。

我的问题是,一旦我开始滚动,一切都变得一团糟。我认为,在滚动“heightForRowAtIndexPath”时,每个显示在屏幕上的单元格不再调用,因此无法计算新的单元格高度。

所以我在这里被困了一段时间。我想知道你们中是否有人可以帮我一把。提前谢谢你。

我会将代码发布到相关文件中。这些文件包括自定义单元格 h 和 m 文件。以及视图控制器m文件的相关功能。

// ######################################################
// HelpTableViewCell.h
#import <UIKit/UIKit.h>

@interface HelpTableViewCell : UITableViewCell  
  IBOutlet UILabel *labelName;
  IBOutlet UILabel *labelDescription;

  IBOutlet UIView *viewBackground;


@property (nonatomic, retain) UILabel *labelName;
@property (nonatomic, retain) UILabel *labelDescription;

@property (nonatomic, retain) UIView *viewBackground;

@end

// ######################################################
// HelpTableViewCell.m
#import "HelpTableViewCell.h"

@implementation HelpTableViewCell

@synthesize labelName;
@synthesize labelDescription;

@synthesize viewBackground;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
  self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

  if (self) 
  

  return self;


- (void)setSelected:(BOOL)selected animated:(BOOL)animated  

  self.labelName.lineBreakMode = UILineBreakModeWordWrap;
  self.labelName.numberOfLines = 0;
  self.labelName.font = [UIFont boldSystemFontOfSize:15];
  [self.labelName sizeToFit];

  self.labelDescription.lineBreakMode = UILineBreakModeWordWrap;
  self.labelDescription.numberOfLines = 0;
  self.labelDescription.font = [UIFont fontWithName:@"Arial" size:15];
  [self.labelDescription sizeToFit];

  [super setSelected:selected animated:animated];


- (void) dealloc  
  [labelName release], labelName = nil;
  [labelDescription release], labelDescription = nil;

  [super dealloc];


@end


// ######################################################
// in my view controller m file
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath    
  static NSString *CellIdentifier = @"HelpTableViewCell";
  HelpTableViewCell *cell = (HelpTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

  if (cell == nil)  
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"HelpTableViewCell" owner:nil options:nil];

    for (id currentObject in topLevelObjects) 
      if ([currentObject isKindOfClass:[UITableViewCell class]])  
        cell = (HelpTableViewCell *) currentObject;
        break;
      
    

  

  cell.labelName.text = [self.instructionName objectAtIndex:indexPath.row];
  cell.labelDescription.text = [self.instructionDescription objectAtIndex:indexPath.row];

  return cell;


- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    NSString *cellText = [self.instructionDescription objectAtIndex:indexPath.row];
    UIFont *cellFont = [UIFont fontWithName:@"Arial" size:15];
    CGSize constraintSize = CGSizeMake(320.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 25;  

【问题讨论】:

【参考方案1】:

如果单元格中的文本要更改,您需要在 tableView 上调用 reloadData,否则 tableView:heightForRowAtIndexPath: 将不会不会被调用。

tableView 的工作方式是在每次重新加载(以及重新加载变体)时收集所有行的高度。这就是 iOS 知道整个表格高度的方式。它不会在抓取单个单元格时再次调用 tableView:heightForRowAtIndexPath:。通常调用 reloadData 非常快,并且此方法与其变体不同,不会导致任何滚动。

有关有用的背景信息,请参阅*** question and answer。

如果您必须做大量工作来计算高度并且您有数百或数千行,就会出现问题。在我有这样的一个用例中,我缓存了行高计算以获得不错的性能。但是,如果这不是您的情况,请对 reloadData 稍微宽松一点。

【讨论】:

【参考方案2】:

有一个很好的教程可以引导您完成确定适合您的文本所需的高度和适当调整单元格高度的过程。

教程可在此处获得:http://www.raddonline.com/blogs/geek-journal/iphone-sdk-resizing-a-uitableviewcell-to-hold-variable-amounts-of-text/

我自己没有尝试过教程中的方法,但看起来很彻底。

希望这会有所帮助!

【讨论】:

【参考方案3】:

您的tableView:heightForRowAtIndexPath: 似乎正确,但您可能需要检查以下有关您的 XIB 文件中 labelDescription 单元格标签的内容:

必须与tableView:heightForRowAtIndexPath: 方法中使用的宽度相匹配(在您的情况下为 320) 必须与tableView:heightForRowAtIndexPath: 方法中使用的字体和大小相匹配(在您的情况下为“Arial”大小 15) 将标签的“调整为适合”复选框设置为否 将 # of lines 属性设置为 0(这样它允许文本跨越多行)

如果您怀疑滚动后没有调用tableView:heightForRowAtIndexPath: 方法,您可以通过在该方法中添加临时NSLog 语句轻松验证这一点。如果它永远不会被调用,您可能忘记将视图控制器设置为 UITableViewUITableViewDelegate 委托。

【讨论】:

以上是关于IOS:具有自定义 uitableviewcell 的动态高度的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell 自定义CG绘制iOS 7

iOS 8和layoutMargin中的自定义UITableViewCells

具有居中 UISlider 和两个图像的自定义 UITableViewCell

IOS:UITableViewCell

带有 UIButton 的自定义 UITableViewCell:单击了哪个按钮?

具有大小类的自调整 UITableViewCells 中的多行 UILabel - iOS 8 和 Swift