IOS:动态高度与自定义的uitableviewcell

问题描述:

我是新的ios开发,这是我迄今为止的问题。我能够通过代理“heightForRowAtIndexPath”动态计算自定义单元格的高度。所以在第一次加载时,每件事情都显示得非常好。IOS:动态高度与自定义的uitableviewcell

我的问题是,只要我开始滚动,一切都只是搞砸了。我认为滚动“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; 
} 

如果在单元格中的文本会改变,你需要在你的tableView通话reloadData当它,否则的tableView:heightForRowAtIndexPath:不会被调用。

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

查看stackoverflow question and answer有用的背景。

如果您必须做大量的工作来计算高度,并且您有成百上千的行,才会出现问题。在一个用例中,我喜欢这个,我缓存行高计算以获得不错的表现。但是,如果这不是你的情况,只需要更加宽松一点,reloadData

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

教程,请访问:http://www.raddonline.com/blogs/geek-journal/iphone-sdk-resizing-a-uitableviewcell-to-hold-variable-amounts-of-text/

我没有试图在本教程自己的方法,但它看起来是相当彻底。

希望这会有所帮助!

tableView:heightForRowAtIndexPath:似乎是正确的,但你可能想检查一下您的XIB文件labelDescription电池标签执行以下操作:

  • 必须在tableView:heightForRowAtIndexPath:方法所使用的宽度(以你的情况,320)
  • 匹配
  • 必须在tableView:heightForRowAtIndexPath:方法中使用的字体和大小相匹配(在你的情况“宋体”大小15)
  • 设置标签的“调整,以适应”复选框,NO
  • 线属性#设置为0(即方式,使文本跨越多行)

如果怀疑tableView:heightForRowAtIndexPath:方法滚动后不会被调用,您可以轻松地验证通过该方法将临时NSLog声明。如果它永远不会被调用,您可能忘记将您的视图控制器设置为UITableViewUITableViewDelegate代表。