2011-08-19 53 views
9

我是新的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; 
} 

回答

4

如果在單元格中的文本會改變,你需要在你的tableView通話reloadData當它,否則的tableView:heightForRowAtIndexPath:不會被調用。

tableView的工作方式是在每次重新載入(和重新載入變體)時收集所有行的高度。這就是iOS知道整個表的高度的方式。它不會調用tableView:heightForRowAtIndexPath:再次抓取單個單元格時。通常調用reloadData是相當快的,這種方法,不像其變種,不會導致任何滾動。

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

如果您必須做大量的工作來計算高度,並且您有成百上千的行,纔會出現問題。在一個用例中,我喜歡這個,我緩存行高計算以獲得不錯的表現。但是,如果這不是你的情況,只需要更加寬鬆一點,reloadData

1

tableView:heightForRowAtIndexPath:似乎是正確的,但你可能想檢查一下您的XIB文件labelDescription電池標籤執行以下操作:

  • 必須在tableView:heightForRowAtIndexPath:方法所使用的寬度(以你的情況,320)
  • 匹配
  • 必須在tableView:heightForRowAtIndexPath:方法中使用的字體和大小相匹配(在你的情況「宋體」大小15)
  • 設置標籤的「調整,以適應」複選框,NO
  • 線屬性#設置爲0(即方式,使文本跨越多行)

如果懷疑tableView:heightForRowAtIndexPath:方法滾動後不會被調用,您可以輕鬆地驗證通過該方法將臨時NSLog聲明。如果它永遠不會被調用,您可能忘記將您的視圖控制器設置爲UITableViewUITableViewDelegate代表。