2013-03-19 1 views
1

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

У меня есть несколько ячеек в UITableView, которые используют другое изображение в зависимости от высоты ячейки (с шагом 50 пикселей, от 50 пикселей до 1000 пикселей в высоту). Я сталкиваюсь с какой-то странной проблемой, когда при первом загрузке приложения cellForRowAtIndexPath сообщает, что первые три ячейки (независимо от того, являются ли все три включенными) имеют высоту 100 пикселей, тогда, когда я прокручиваю вниз и снова создаю резервную копию, их высота вернется к правильному значению. На экране нет изменения высоты экрана, только изменения, используемые изображения, и значение cell.frame.size.height в моих NSLog операциях.

Я вхожу в систему heightForRowAtIndexPath и cellForRowAtIndexPath, и я могу проверить правильность высот, когда они покидают heightForRowAtIndexPath. Но при вводе cellForRowAtIndexPath эти первые три высоты установлены равномерно на 100. Затем я прокручиваю вниз до тех пор, пока эти три ячейки не будут отображаться на экране, затем прокрутите назад, а значениеизменится на правильное значение.

Итак, мои вопросы:

Есть ли код называется между самим концом heightForRowAtIndexPath и в самом начале cellForRowAtIndexPath, что можно было бы меняющимся значение этих первых нескольких ячеек cell.frame.size.height?

Почему эта проблема возникает только в первых трех ячейках? И почему бы им вернуться после перезагрузки через мгновение? Я думал, что причиной повторного использования может быть идентификатор повторного использования, но они по-прежнему назначают этот идентификатор при первой загрузке, так что это не имеет значения, не так ли?

EDIT: Я думаю, что 100px высота исходит от высоты строки ячейки прототипа в моей раскадровки, как если бы я изменить это на 101px, эти первые три клетки затем первоначально в 101px.

EDIT: Вот код, я использую, чтобы установить изображение, хотя эта часть работает, он только что получил неверное значение для работы с:

UIImage *cappedBG; 
float cellHeight = cell.contentView.frame.size.height; 

if (cellHeight <= 51) { 
    cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch]; 
} else if (cellHeight <= 101) { 
    cappedBG = [[UIImage imageNamed: @"bg100.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch]; 
} else if (cellHeight <= 151) { 
    cappedBG = [[UIImage imageNamed: @"bg150.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch]; 
} else if (cellHeight <= 201) { 
    cappedBG = [[UIImage imageNamed: @"bg200.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch]; 
} else { 
    cappedBG = [[UIImage imageNamed: @"bg250.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch]; 
} 

ответ

4

Вы просто не можете положиться на кадр ячейки в tableView:cellForRowAtIndexPath:. Кадр ячейки, которую вы настраиваете в этом методе, будет установлен после возврата кода из этого метода.

Значения, которые вы получаете, не являются фактическими высотами этой конкретной строки. Вы получаете высоту из ячейки, которая только что была удалена. Если нет ячейки для удаления очереди из используемой ячейки, она будет создана. И 100, вероятно, является высотой ячейки в вашем раскадровке/nib.
Эта высота не имеет ничего общего с высотой ячейки, которая будет отображаться.

Поскольку вы вычисляете высоту строки в tableView:heightForRowAtIndexPath:, используйте это значение.

float cellHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath]; 

if (cellHeight <= 51) { 
    cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch]; 
... 
+0

Похоже, это получилось. Дайте несколько минут, чтобы проверить, и я буду отмечать это правильно. – Luke

+0

вы гений ..! – ViruMax

1

Вы не должны действительно делать компоновка ячейки в cellForRowAtIndexPath.

Лучший способ сделать это - создать подкласс UITableViewCell со всеми элементами пользовательского интерфейса, которые вам нужны.

Затем в подкласс вы можете переопределить - (void)layoutSubviews.

Таким образом, вы держите все отдельно, а не помещаете ВСЁ в контроллер вида.

+0

У меня уже есть пользовательские ячейки на месте, но я взаимодействие с 'CoreData' и' NSFetchedResultsController', так что очень запутанно, чтобы отправить данные в пользовательских ячейках подкласс оттуда для укладки его. Если я размещаю ячейку там, то все методы, которые я вызываю в подклассе, все равно будут вызываться каждый раз, когда я просматриваю таблицу и т. Д.? Я думал, что «cellForRowAtIndexPath» было местом, где Apple рекомендовала вам заполнить ячейку. Все еще довольно новое. – Luke

1

В настоящее время, посмотрев на ваш вопрос, я думаю, что у вас проблемы с разной высотой ячейки (при прокрутке). Я считаю, что вы не указали правильные значения в heightForRowAtIndexPath.

Ниже приведен простой код, который я написал. Этот код имеет отображает 20 строк в таблице и чередуются строка имеет различный размер. (Я использовал различные цвета, чтобы отличить)

#pragma mark - TableView DataSource Methods 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if(indexPath.row %2 == 0) return 50; 
    else return 100; 
} 

// Customize the number of sections in the table view. 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 


// Customize the number of rows in the table view. 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return 20; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *stringCellIdentifier = @"BookOutVehicleCell"; 

    UITableViewCell *tableViewCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:stringCellIdentifier]; 

    if (tableViewCell == nil) 
     tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:stringCellIdentifier] autorelease]; 

    if(indexPath.row %2 == 0) tableViewCell.contentView.backgroundColor = [UIColor redColor]; 
    else tableViewCell.contentView.backgroundColor = [UIColor greenColor]; 

     return tableViewCell; 

} 

#pragma mark - TableView Delegate Methods 
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

} 

Это выход.

enter image description here

В этом случае, даже если мы прокручивать Tableview вверх и вниз, высота строки не меняется.

Надеюсь, это поможет. И извините, если я неправильно понял ваш вопрос. Было бы неплохо, если бы вы предоставили фрагмент кода. Это даст нам лучшее представление о проблеме.

EDIT: Согласно моему пониманию этого вопроса вы получаете правильные высоты для каждой строки/ячейки, однако вы использовали ImageView в ячейку, которая будет отображать различные изображения, как на высоте клетки. Убедитесь, что для вас работает следующее:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     static NSString *stringCellIdentifier = @"BookOutVehicleCell"; 

     UITableViewCell *tableViewCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:stringCellIdentifier]; 

     if (tableViewCell == nil) 
      tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:stringCellIdentifier] autorelease]; 

     //Check your height here and use appropriate image 
     if(cell.contentView.frame.size.height <100) 
     { 
      image = "xxx.png"; 
     } 
     else 
     if(cell.contentView.frame.size.height >=100 && cell.contentView.frame.size.height <200) 
     { 
      image = "yyy.png"; 
     } 


    } 

Спасибо.

+0

Высоты устанавливаются должным образом в приложении, так как текст не перекрывается на следующую ячейку и т. Д. Это правильно нарисовано, но значение высоты неверно. Я даже не знаю, как это возможно! – Luke

+0

Что вы подразумеваете под этим ** «Это правильно нарисовано, но значение высоты неверно». **? Было бы полезно понять проблему, если вы предоставите фрагмент кода. – Kunal

+0

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

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