Как рассчитать heightForRowAtIndexPath для ячеек, которые настраиваются через переключатель в cellForRowAtIndexPath - PullRequest
3 голосов
/ 12 января 2012

Я настраиваю свои ячейки следующим образом:

Итак, пара переключателей определяет ячейки, потому что данные находятся не в списке объектов, а набор информации, которая должна отображаться в табличном представленииразными способами.

-(UITableViewCell *)value1CellForTableView:(UITableView *)tableView {
    static NSString *CellIdentifierValue1 = @"Value1Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierValue1];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifierValue1];
        cell.detailTextLabel.textAlignment = UITextAlignmentLeft;
        cell.textLabel.textAlignment = UITextAlignmentLeft;
    }
    return cell;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = nil;

    switch (indexPath.section) {
        case 0:
            //Coupon
            switch (indexPath.row) {
                case 0:
                    //Couponcode
                    cell = [self value1CellForTableView:tableView];
                    cell.textLabel.text = @"Code";
                    cell.detailTextLabel.text = presentedCoupon.couponNr;
                    break;
                case 1:
                    //Coupondescription
                    cell = [self value1CellForTableView:tableView];
                    cell.detailTextLabel.text = presentedCoupon.couponDescription;
                    cell.detailTextLabel.numberOfLines = 0;
                    cell.textLabel.text =@"Ihr Vorteil";
                    break;

            }        
            break;


        case 1:
            //Productinfo
            switch (indexPath.row) {
                case 0:
                    cell = [self defaultCellForTableView:tableView];
                    cell.imageView.image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath]  stringByAppendingPathComponent: [presentedCoupon.refProdName stringByAppendingString:@".png"]]];
                    cell.textLabel.text = presentedCoupon.refProdName;
                    break;



            }
            break;  

        case 2:
            //Shopinfo
            switch (indexPath.row) {
                case 0:
                    cell = [self defaultCellForTableView:tableView];
                    cell.textLabel.text = ((Shop*)presentedCoupon.refShop).name;
                    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

                    break;    
            }
            break;       
    }

    if (cell == nil) {
        cell = [self defaultCellForTableView:tableView];
        cell.textLabel.text = @"Stanni";
    }
    [cell layoutIfNeeded];
    return cell;
}

И я вычисляю высоту вот так.

 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        NSLog(@"height");
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];

    CGFloat height = 24 + [cell.detailTextLabel.text sizeWithFont:cell.detailTextLabel.font constrainedToSize: CGSizeMake(cell.detailTextLabel.frame.size.width, 1000.0f) lineBreakMode:cell.detailTextLabel.lineBreakMode].height;

    return MAX(height, 44.0f);

Проблема:

Проблема в том, что, как упоминалось во многих темах, а также в моем журнале видно, что высота каждой ячейки (видимая илинет) спрашивается при инициализации табличного представления.Таким образом, в более чем 100+ списках также создаются более 100 ячеек -> теряются при запуске.

Есть ли другая возможность получить эту информацию, когда ячейка настроена следующим образом?Действительно ли необходимо снова построить структуру регистра переключателей в heightForRowAtIndexPath, чтобы избежать этих вызовов и получить правильную высоту для каждой ячейки?

Было бы лучше иметь «список источников данных» с единственной информацией о каждой ячейке?

Но как обрабатывать различные стили ячеек, пользовательские ячейки.

Ответы [ 4 ]

5 голосов
/ 12 января 2012

Способ

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

вызывается для каждой ячейки перед методом

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

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

Когда вы создаете tableView, у источника данных сначала запрашивается номер строки. Затем для каждой строки у источника данных запрашивается высота строки, чтобы tableView знал общую высоту своего содержимого, и, наконец, у источника данных запрашивается ячейка (фактическое представление) для отображения.

В вашем случае я бы снова построил структуру корпуса коммутатора. Что касается «списка источников данных», я никогда не делал этого раньше, так что, возможно, это лучшее решение.

4 голосов
/ 12 января 2012

Две возможности:

  1. Сколько у вас клеток?Если у вас есть небольшое количество ячеек (что, кажется, имеет место здесь), вам не нужно повторно использовать ячейки!Как правило, повторное использование клеток является чрезмерным.Просто создайте ячейки, когда вы создаете свой контроллер или когда вы обновили свои данные и поместите их в NSArray.
    Затем вы можете вернуть их из tableView:cellForRowAtIndexPath: или измерить их высоту.

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

2 голосов
/ 11 декабря 2013

Если у вас есть массив строк в объектах и ​​вы используете стандартную ячейку таблицы, попробуйте это волшебство, совместимое с iOS 7:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString* text = [self.objects objectAtIndex:indexPath.row];
    NSAttributedString * attributedString = [[NSAttributedString alloc] initWithString:text attributes:
                                             @{ NSFontAttributeName: [UIFont systemFontOfSize:18]}];

    //its not possible to get the cell label width since this method is called before cellForRow so best we can do
    //is get the table width and subtract the default extra space on either side of the label.
    CGSize constraintSize = CGSizeMake(tableView.frame.size.width - 30, MAXFLOAT);

    CGRect rect = [attributedString boundingRectWithSize:constraintSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];

    //Add back in the extra padding above and below label on table cell.
    rect.size.height = rect.size.height + 23;

    //if height is smaller than a normal row set it to the normal cell height, otherwise return the bigger dynamic height.
    return (rect.size.height < 44 ? 44 : rect.size.height);
}
0 голосов
/ 12 января 2012

Как я вижу - у вас есть только два типа клеток.Таким образом, у вас может быть @property для каждого типа ячейки (пожалуйста, посмотрите на пример ниже):

static NSString * const kCellIdentifier = @"kCellIdentifier";

@interface ...
@property (nonatomic, retain) UITableViewCell *cell;
@end

@implementation
@synthesize cell = cell_;

...

- (UITableViewCell *)cell {
    if (!cell_) {
        cell_ = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellIdentifier];
    }
    return cell_;
}

- (UITableViewCell *)cellForTableView:(UITableView *)tableView {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
    if (!cell) {
        //put it to autorelease pool to avoid EXC_BAD_ACCESS
        cell = [[self.cell retain] autorelease];
        self.cell = nil;
    }
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = self.cell;
    CGFloat height = 24 + [@"text" sizeWithFont:cell.detailTextLabel.font constrainedToSize: (CGSize){cell.detailTextLabel.frame.size.width, CGFLOAT_MAX} lineBreakMode:cell.detailTextLabel.lineBreakMode].height;
    return MAX(height, 44.0f);
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self cellForTableView:tableView];
    cell.detailTextLabel = @"text";
    return cell;
}

Таким образом, ячейка будет инициализирована только один раз в начале.

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