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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7128215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:11:31  来源:igfitidea点击:

IOS: dynamic height with a custom uitableviewcell

iphoneobjective-ciosuitableviewios4

提问by Daniel Nguyen

I am new at ios development and this is my problem thus far. I am able to dynamically calculate the height of a custom cell via the delegate "heightForRowAtIndexPath". So on the first load, every thing is display perfectly fine.

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

My problem is as soon as I start scrolling, everything just messes up. I think that while scrolling the "heightForRowAtIndexPath" is no longer called per cell that get display on screen, so the new cell height cannot be calculated.

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

So I've been stuck here for a while. I was wondering if any of you could lend me a hand. thank you in advance.

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

I'll post the code to relevant files. These files include the custom cell h and m file. and relevant functions of the view controller m file.

我会将代码发布到相关文件中。这些文件包括自定义单元格 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;  
}

采纳答案by Obliquely

If the text in the cells is going to change, you will need to a call reloadDataon your tableView when it does, otherwise the tableView:heightForRowAtIndexPath: won't be called.

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

The way the tableView works is that it gathers the heights for all rows at every reload (and the reload variants). This is how iOS knows the height of the entire table. It doesn't call tableView:heightForRowAtIndexPath: again when grabbing individual cells. Usually calling reloadDatais quite quick and this method, unlike its variants, doesn't cause any scrolling.

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

See stackoverflow question and answerfor useful background.

有关有用的背景信息,请参阅stackoverflow 问答

Problems arise if you have to do a lot of work to calculate heights and you have hundreds or thousands of rows. In one use case I have like this, I cache the row height calculations to get decent performance. But if that's not your case, just be a little more liberal with reloadData.

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

回答by superjessi

There is a good tutorial that walks you through the process of determining the height that is required to fit your text and sizing the cell height appropriately.

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

the tutorial is available here: http://www.raddonline.com/blogs/geek-journal/iphone-sdk-resizing-a-uitableviewcell-to-hold-variable-amounts-of-text/

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

I have not attempted the methods in the tutorial myself, but it looks to be pretty thorough.

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

Hope this helps!

希望这可以帮助!

回答by pythonquick

Your tableView:heightForRowAtIndexPath:seems correct, but you might want to check the following about the labelDescription cell label in your XIB file:

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

  • must match the width used in the tableView:heightForRowAtIndexPath:method (in your case, 320)
  • must match the font and size used in the tableView:heightForRowAtIndexPath:method (in your case "Arial" size 15)
  • set the label's "Adjust to fit" checkbox to NO
  • set the # of lines property to 0 (that way it allows the text to span multiple lines)
  • 必须与tableView:heightForRowAtIndexPath:方法中使用的宽度相匹配(在您的情况下为 320)
  • 必须与tableView:heightForRowAtIndexPath:方法中使用的字体和大小相匹配(在您的情况下,“Arial”大小为 15)
  • 将标签的“调整以适合”复选框设置为“否”
  • 将 # of lines 属性设置为 0(这样它允许文本跨越多行)

If you suspect the tableView:heightForRowAtIndexPath:method does not get called after you scroll, you can easily verify that by adding a temporary NSLogstatement in that method. If it never gets called, you might have forgotten to set your view controller as the UITableView's UITableViewDelegatedelegate.

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