2013-02-15 2 views
1

У меня есть UItableview, который я заполняю данными, используя heightForRowAtIndexPath и cellForRowAtIndexPath. По-видимому, Apple заставляет меня делать что-то в своем коде дважды.Уродливая высотаForRowAtIndexPath и cellForRowAtIndexPath

Прежде всего, я должен рассчитать размер моих просмотров (для этого я должен их сделать) в heightForRowAtIndexPath, а затем я должен сделать их снова, чтобы добавить их в фактический вид.

У меня довольно сложный вид, поэтому он выглядит двойным уродством, когда вам приходится писать его дважды.

Нет ли лучшего способа сделать это?

UPDATE

Это как мой код выглядит. Это не совсем то же самое, но довольно близко. Почему в мире яблоко заставляет меня писать это дважды?

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    NSLog(@"heightForRowAtIndexPath"); 

    //Initiating strings 
    NSString *headlineString; 
    NSString *subHeadlineString; 
    NSString *bylineString; 
    if (global.magazine.issues.count==0) { 
     return 45; 
    }else if(indexPath.section == global.magazine.issues.count+1) { 
     //Finding the right issue and article for this row 
     Issue *issue = [global.magazine.issues objectAtIndex:global.magazine.issues.count-1]; 

     //Creating the headline 
     headlineString = [NSString stringWithFormat:@"<span class='bold_style'>FOREWORD</span>"]; 

     //Creating the subHeadline 
     subHeadlineString = [NSString stringWithFormat:@"%@", [issue.magazine_foreword substringToIndex:100]]; 

     //Creating byline 
     bylineString = [[NSString stringWithFormat:@"<span class='ital_style'>By %@</span>", issue.magazine_byline] capitalizedString]; 
    }else{ 
     //Finding the right issue and article for this row 
     Issue *issue = [global.magazine.issues objectAtIndex:indexPath.section-1]; 
     Article *article = [issue.articles objectAtIndex:indexPath.row]; 

     //Creating the headline 
     headlineString = [NSString stringWithFormat:@"<span class='bold_style'>%@</span>", [article.title uppercaseString]]; 

     //Creating the subHeadline 
     subHeadlineString = [NSString stringWithFormat:@"%@", [article.main_text substringToIndex:100]]; 

     //Creating byline 
     bylineString = [NSString stringWithFormat:@"<span class='ital_style'>By %@</span>", article.byline]; 
    } 

    //Creating the labels 
    NMCustomLabel *headline = [global.label headLineLabelWithString:headlineString fromTop:30 withWidth:global.screenWidth-60]; 
    NMCustomLabel *subHeadline = [global.label subHeadlineLabelWithString:subHeadlineString fromTop:30+headline.height+10 withWidth:global.screenWidth-60]; 
    NMCustomLabel *byline = [global.label articleBylineLabelWithString:bylineString fromTop:30+headline.height+10+subHeadline.height+10 withWidth:global.screenWidth-60]; 

    //Setting the height of the row 
    return 30+headline.height+10+subHeadline.height+10+byline.height+30; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    NSLog(@"cellForRowAtIndexPath"); 
    //Preparing the cell 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] 
       initWithStyle:UITableViewCellStyleDefault 
       reuseIdentifier:CellIdentifier]; 
    } 

    //Removing former text views 
    for (UIView *subview in [cell subviews]) { 
     if (subview.tag == 21 || subview.tag == 22 || subview.tag == 23) [subview removeFromSuperview]; 
    } 

    //Removing and setting tableview border 
    [[cell viewWithTag:30] removeFromSuperview]; 
    UIView *rightBorder = [[UIView alloc] initWithFrame:CGRectMake(cell.width-1, 0, 1, cell.height)]; 
    rightBorder.backgroundColor = global.lightGrey; 
    rightBorder.tag = 30; 
    [cell addSubview:rightBorder]; 

    //Setting the seletion background color on the cells 
    UIView *bgColorView = [[UIView alloc] init]; 
    bgColorView.backgroundColor = global.extraLightGrey; 
    cell.selectedBackgroundView = bgColorView; 
    if (global.magazine.issues.count==0) { 
     return cell; 
    }else if (indexPath.section-1 == global.magazine.issues.count) { 
     //Finding the right issue and article for this row 
     Issue *issue = [global.magazine.issues objectAtIndex:global.magazine.issues.count-1]; 

     //Creating the headline 
     NSString *headlineString = [NSString stringWithFormat:@"<span class='bold_style'>FOREWORD</span>"]; 
     NMCustomLabel *headline = [global.label headLineLabelWithString:headlineString fromTop:30 withWidth:global.screenWidth-60]; 
     headline.tag = 21; 
     [cell addSubview:headline]; 

     //Creating the subHeadline 
     NSString *subHeadlineString = [[NSString stringWithFormat:@"%@", issue.magazine_foreword] substringToIndex:100]; 
     NMCustomLabel *subHeadline = [global.label subHeadlineLabelWithString:subHeadlineString fromTop:30+headline.height+10 withWidth:global.screenWidth-60]; 
     subHeadline.tag = 22; 
     [cell addSubview:subHeadline]; 

     //Creating byline 
     NSString *bylineString = [[NSString stringWithFormat:@"<span class='ital_style'>By %@</span>", issue.magazine_byline] capitalizedString]; 
     NMCustomLabel *byline = [global.label articleBylineLabelWithString:bylineString fromTop:30+headline.height+10+subHeadline.height+10 withWidth:global.screenWidth-60]; 
     byline.tag = 23; 
     [cell addSubview:byline]; 
    }else{ 
     //Finding the right issue and article for this row 
     Issue *issue = [global.magazine.issues objectAtIndex:indexPath.section-1]; 
     Article *article = [issue.articles objectAtIndex:indexPath.row]; 

     //Creating the headline 
     NSString *headlineString = [NSString stringWithFormat:@"<span class='bold_style'>%@</span>", [article.title uppercaseString]]; 
     NMCustomLabel *headline = [global.label headLineLabelWithString:headlineString fromTop:30 withWidth:global.screenWidth-60]; 
     headline.tag = 21; 
     [cell addSubview:headline]; 

     //Creating the subHeadline 
     NSString *subHeadlineString = [NSString stringWithFormat:@"%@", [article.main_text substringToIndex:100]]; 
     NMCustomLabel *subHeadline = [global.label subHeadlineLabelWithString:subHeadlineString fromTop:30+headline.height+10 withWidth:global.screenWidth-60]; 
     subHeadline.tag = 22; 
     [cell addSubview:subHeadline]; 

     //Creating byline 
     NSString *bylineString = [[NSString stringWithFormat:@"<span class='ital_style'>By %@</span>", article.byline] capitalizedString]; 
     NMCustomLabel *byline = [global.label articleBylineLabelWithString:bylineString fromTop:30+headline.height+10+subHeadline.height+10 withWidth:global.screenWidth-60]; 
     byline.tag = 23; 
     [cell addSubview:byline]; 
    } 

    return cell; 
} 
+0

Можете ли вы опубликовать снимок экрана, если это возможно? – Rushi

+0

@ Rushi См. Выше. Думайте, что это смешное дизайнерское решение от Apple, чтобы сделать это таким образом. Кажется немного отсталым. –

+2

Вы всегда можете реализовать свой собственный вид. Я почти уверен, что вам не понадобится много времени, чтобы понять, почему нужно знать всю высоту заранее. Или живите с запаздывающим столом и вычисляйте высоты ячеек при создании статей и кешируйте их в объекте статьи. –

ответ

0
heightForRowAtIndexPath 

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

Есть один способ избежать этого. Но я не советую вам пойти на это. Потому что это изменит дизайн вашего UITableView. Что вы можете сделать, так это то, что вы можете выбрать максимальную высоту своей строки из всех возможных условий. Напр. Давайте рассмотрим это как 100 пикселей. Затем вы можете нарисовать остальную часть ячеек. Однако это останется пустым пространством, если какая-либо из ваших строк меньше 100 пикселей. И это будет выглядеть лохматым.

В принципе, чтобы удовлетворить ваши требования, вам придется сделать это дважды. Нет другого выбора :-(

+0

Черт. Это печально слышать. И нет способа, чтобы я мог установить высоту где-то в другом месте. Как в cellForRowAtIndexPath? –

+1

Нет, вы не можете установить высоту внутри cellForRowAtIndexPath. – Rushi

2

Самое простое решение не следовать СУХОЙ принципам и либо добавить высоту как свойство объектов, которые вы используете в качестве источника данных или добавить метод к контроллеру представления, такие как:

-(CGFloat)calculateHeightForHeadline:(NSString*)headline andSubHeadline:(NSString*)subHeadline andByLine:(NSString*)byLine 

Тогда по крайней мере, у вас есть только код расчета в одном месте.

в качестве альтернативы, можно назвать [tableView heightForRowAtIndexPath:indexPath] из метода cellForRowAtIndexPath

+0

Похоже, это может облегчить боль. Благодарю. Что бы вы назвали heightForRowAtIndexPath из cellForRowAtIndexPath, хотя? –

2

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

Я не знаю то, что вы делаете в пользовательских классах ярлыков, но вы можете рассчитать высоту без необходимости создавать представления (что дорого), используя строковые или атрибутные строковые чертежи и расчет размера UIKit extensions, которые были созданы для этой цели.

0

Интересно, почему вы создаете свои собственные ярлыки в heightForRowAtIndexpath? Почему бы вам просто не рассчитать размер текста с помощью sizeWithFont: или таких методов? Я думаю, что это лучший способ рассчитать высоту строки. Удачи!

+0

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

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