IOS: динамическая высота с настраиваемой uitableviewcell - PullRequest
10 голосов
/ 20 августа 2011

Я новичок в разработке ios, и это моя проблема до сих пор. Я могу динамически рассчитать высоту пользовательской ячейки с помощью делегата "heightForRowAtIndexPath". Итак, при первой загрузке все отображается отлично.

Моя проблема в том, что как только я начинаю прокручивать, все просто портится. Я думаю, что при прокрутке «heightForRowAtIndexPath» больше не вызывается для каждой ячейки, отображаемой на экране, поэтому высоту новой ячейки вычислить невозможно.

Так что я застрял здесь на некоторое время. Мне было интересно, если кто-нибудь из вас может помочь мне. заранее спасибо.

Я выложу код в соответствующие файлы. Эти файлы включают в себя пользовательские ячейки h и m file. и соответствующие функции файла контроллера представления 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 голосов
/ 20 августа 2011

Если текст в ячейках изменится, вам нужно будет вызвать reloadData в вашем tableView, когда это произойдет, в противном случае tableView: heightForRowAtIndexPath : не будетnamed.

Способ работы tableView заключается в том, что он собирает высоты для всех строк при каждой перезагрузке (и варианты перезагрузки).Это то, как iOS знает высоту всей таблицы.Он не вызывает tableView: heightForRowAtIndexPath : снова при захвате отдельных ячеек.Обычно вызов reloadData довольно быстрый, и этот метод, в отличие от его вариантов, не вызывает прокрутки.

См. вопрос stackoverflow и ответ для получения полезной информации.

Проблемы возникают, если вам приходится много работать для вычисления высоты, а у вас есть сотни или тысячи строк.В одном случае использования, который у меня есть, я кеширую вычисления высоты строк, чтобы получить приличную производительность.Но если это не ваш случай, просто будьте немного либеральнее с reloadData .

3 голосов
/ 20 августа 2011

Существует хороший учебник, который проведет вас через процесс определения высоты, необходимой для размещения вашего текста, и правильного определения размера ячейки.

учебник доступен здесь: http: //www.raddonline.com/blogs/geek-journal/iphone-sdk-resizing-a-uitableviewcell-to-hold-variable-amounts-of-text/

Я не пробовал методыв учебнике, но это выглядит довольно тщательно.

Надеюсь, это поможет!

1 голос
/ 20 августа 2011

Ваш tableView:heightForRowAtIndexPath: кажется правильным, но вы можете проверить следующее о метке ячейки labelDescription в файле XIB:

  • должно соответствовать ширине, используемой в методе tableView:heightForRowAtIndexPath: (вв вашем случае, 320)
  • должен соответствовать шрифту и размеру, используемому в методе tableView:heightForRowAtIndexPath: (в вашем случае «Arial», размер 15)
  • установите флажок «Adjust to fit» на меткеNO
  • установите для свойства # of lines значение 0 (таким образом, он позволяет тексту занимать несколько строк)

Если вы подозреваете, что метод tableView:heightForRowAtIndexPath: не вызывается после васпрокручивая, вы можете легко проверить это, добавив временную инструкцию NSLog в этот метод.Если он никогда не вызывается, вы, возможно, забыли установить свой контроллер представления как UITableView 'UITableViewDelegate делегат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...