iOS:使用自定义UITableViewCell实现动态高度

10

我是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;  
}
3个回答

4
如果单元格中的文本将会改变,那么在更改后您需要调用reloadData来刷新您的tableView,否则tableView:heightForRowAtIndexPath就不会被调用。
tableView的工作方式是在每次重新加载(和其变体)时收集所有行的高度。这就是iOS知道整个表的高度的方法。当获取单个单元格时,它不会再次调用tableView:heightForRowAtIndexPath。通常,调用reloadData非常快,并且与其变体不同,它不会引起任何滚动。
请参见stackoverflow问题和答案以获取有用的背景信息。
如果您需要计算大量行的高度并且有数百或数千行,则会出现问题。在我遇到的一个这样的用例中,我缓存了行高计算以获得良好的性能。但如果这不是您的情况,请稍微宽容一些,多使用reloadData

3

1

你的tableView:heightForRowAtIndexPath:看起来是正确的,但你可能需要检查一下XIB文件中labelDescription单元格标签的以下内容:

  • 必须与tableView:heightForRowAtIndexPath:方法中使用的宽度匹配(在你的情况下,为320)
  • 必须与tableView:heightForRowAtIndexPath:方法中使用的字体和大小匹配(在你的情况下为"Arial"大小15)
  • 将标签的“调整大小以适应”复选框设置为NO
  • 将行数属性设置为0(这样可以允许文本跨越多行)

如果你怀疑在滚动后tableView:heightForRowAtIndexPath:方法没有被调用,你可以通过在该方法中添加一个临时的NSLog语句来轻松验证。如果它从未被调用过,那么你可能忘记将你的视图控制器设置为UITableViewUITableViewDelegate代理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接