2013-09-22 2 views
0

UILabel внутри ячейки содержит NSLocalizedString; варьируя от нескольких символов до абзаца в зависимости от языка. Кадр UILabel когда-то делает, и иногда не рисует, чтобы соответствовать длине строки. Я считаю, что это проблема повторного использования, но я не понимаю, как это исправить.Корректировка размера UILabel в UITableViewCell, загруженном из Nib

У меня есть ряд из пяти различных подклассов UITableViewCell, загруженных из перьев (требование проекта) в viewDidLoad:

UINib *Cell1Nib = [UINib nibWithNibName:@"customCell1" bundle:nil]; 
[[self tableView] registerNib:Cell1Nib forCellReuseIdentifier:@"custCell1"]; 

UINib *Cell2Nib = [UINib nibWithNibName:@"customCell2" bundle:nil]; 
[[self tableView] registerNib:Cell2Nib forCellReuseIdentifier:@"custCell2"]; 
//etc. 

У меня есть помощник для получения высоты UILabel в зависимости от текста, используемая:

- (CGFloat)getTextHeight:(NSString *)locStr forLabelWidth:(CGFloat)w { 
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, w, 110)]; 
    label.numberOfLines=0; 
    label.lineBreakMode=NSLineBreakByCharWrapping; 
    label.text = locStr; // highly variable & already localized 
    label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; 
    CGSize maxSize = CGSizeMake(w, CGFLOAT_MAX); 
    CGSize requiredSize = [label sizeThatFits:maxSize]; 
    label = nil; // ARC paranoia 
    return requiredSize.height; 
} 

В heightForRowAtIndexPath Я вызываю getTextHeight:forLabelWidth:, используя его для определения высоты ячейки и сохранения результата в NSMutableArray, который называется labelHeightforRow.. Пока все отлично работает.

создать таблицу как таковую:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = nil; 
    DLX_CellDescriptor *desc = [[DLX_CellDescriptor alloc] initWithRow:indexPath.row]; 
    //DLX_CellDescriptor describes attributes for cell at index , essentially a list of strings 
    CGFloat helpTextHeight = [[labelHeightforRow objectAtIndex:indexPath.row] floatValue]; 

    if ([desc.nibToUse caseInsensitiveCompare:@"custCell1"] == NSOrderedSame) { 
     DLX_CustCell1 *currCell = (DLX_CustCell1 *)[self.tableView dequeueReusableCellWithIdentifier:@"custCell1"]; 
     CGPoint origin = currCell.theLabel.frame.origin; 
     CGFloat w = currCell.theLabel.frame.size.width; 
     currCell.theLabel.frame = CGRectMake(origin.x, origin.y, w, helpTextHeight); 
     currCell.theLabel.text = desc.localizedText; 
     currCell.theLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; 
     currCell.tag = indexPath.row; 
     cell = currCell; 
    } else if ([desc.nibToUse caseInsensitiveCompare:@"custCell2"] == NSOrderedSame) { 
     DLX_CustCell2 *currCell = (DLX_CustCell2 *)[self.tableView dequeueReusableCellWithIdentifier:@"custCell2"]; 
     CGPoint origin = currCell.theLabel.frame.origin; 
     CGFloat w = currCell.theLabel.frame.size.width; 
     currCell.theLabel.frame = CGRectMake(origin.x, origin.y, w, helpTextHeight); 
     currCell.theLabel.text = desc.localizedText; 
     currCell.theLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; 
     currCell.tag = indexPath.row; 
     cell = currCell; 
    } // for about 26 rows of 5 different non-identical sytles 
     // simplified in this example 
    return cell; 
} 

Эта проблема в том, что, когда первоначальный TableView создан, UILabel высота указана в СИБ: обрезается дополнительный длинный текст и дает большое пустое пространство под (от правильной регулировки высоты ячейки). Когда таблица перерисовывается, UILabel превращается в правильную высоту, указанную в коде; показывая всю строку. Затем, если ячейка воссоздана; скажем, после того, как он прокручивается с экрана, а другой из его типа ячейки нарисован, длинная текстовая метка снова использует высоту усечения от Nib.

Я попытался положить layoutSubviews в обычай UITableViewCell (customCell1.m, например), как например:

- (void)layoutSubviews { 
    NSInteger currCell = self.tag; 
    DLX_CellDescriptor *desc = [[DLX_CellDescriptor alloc] initWithRow:currCell]; 
    CGPoint origin = theLabel.frame.origin; 
    CGSize size = theLabel.frame.size; 
    CGFloat textHeight = [self getTextHeight:desc.localizedText forLabelWidth:size.width]; 
    theLabel.frame = CGRectMake(origin.x, origin.y, size.width, textHeight); 
    [super layoutSubviews]; 
} 

Но это имело эффект непреложно обеспечения, которая использовалась высота от СИБ; хотя при осмотре textheight был верным (и, для некоторых языков, намного больше высоты Ниба.)

ответ

1

С этой точки зрения ваша камера относительно проста, один простой способ решить вашу проблему - не использовать повторное использование. Просто загрузите файл nib из пакета. Удалите эти коды registerNib. И сделайте это так:

NSString *reuseIdentifier = @"DistrictCellReuseIdentifier"; 
DistrictCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 
if (cell == nil) { 
    cell = [[NSBundle mainBundle] loadNibNamed:@"DistrictCell" owner:self options:nil][0]; 
} 
+0

Я решительно упростил пример кода, который я задал в вопросе, чтобы не загромождать вопрос. Фактические ячейки имеют UIControls, изображения, фоны, функциональность аккордеона и т. Д. Однако я не знаком с отключением повторного использования. Не могли бы вы рассказать? – NSConfusedCoder

+0

@NSConfusedCoder ответ обновлен. – sunkehappy

+0

Предлагаемый код, если он реализован как введенный, привел к другому способу получения такой же ошибки. Однако он указал мне на правильный путь. Я полагаю, что проблема повторного использования заключалась в том, чтобы убедиться, что reuseIdentifier был уникальным, как 'NSString * reuseIdentifier = [NSString stringWithFormat: @" CellReuseIdentifier% d ", indexPath.row];' – NSConfusedCoder

Смежные вопросы