2013-03-01 1 views
3

У меня есть UITableViewCell, и мне нужно случайно помещать межстраничные изображения в некоторые из них. Это работает, но из-за кэширования ячеек изображения снова повторяются вниз по таблице. Предположим, что я предварительно решил разместить изображения в ячейках 1, 12 и 25, эти ячейки будут иметь свои изображения, но после ячейки 1 ячейки 4, 8 и т. Д. Могут также содержать это первое изображение.UIImageViews в UITableViewCells воссоздают себя в кэшированных ячейках

Я угадываю, что мне нужно сделать, это конкретно указать cellForRowAtIndexPath очистить кэш и удалить любые изображения, если он не соответствует критериям для добавления изображения. Как мне это сделать? Я уже пробовал else в инструкции if, которая принимает решение и назначает изображение. В этом else я попытался установить изображение UIImageView на nil, но это не имеет никакого значения.

Есть ли другой способ очистить кеш, чтобы эти изображения не могли спамить свой путь вниз по странице через равные промежутки времени? Вот мой метод cellForRowAtIndexPath, и строки, которые в настоящий момент находятся в последнем else, не оказывают никакого влияния на изображения, поэтому они (я думаю) должны заменить что-то, что работает!

- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath 
{ 
    // Make and allocate the cell if necessary. 
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier: @"Cell"]; 
    if (cell == nil) { 
     cell = [[CustomCell alloc] initWithStyle: UITableViewCellStyleValue1 reuseIdentifier: @"Cell"]; 
    } 
    cell.lineLabel.text = [[self.fetchedResultsController objectAtIndexPath: indexPath] line]; 
    cell.actorLabel.text = [[self.fetchedResultsController objectAtIndexPath: indexPath] actor]; 
    [cell.lineLabel sizeToFitMultipleLines]; 

    // Get the size each label needs to be when constrained to set width and very long height (8000). 
    CGSize labelSize = [cell.lineLabel.text sizeWithFont: cell.lineLabel.font constrainedToSize: CGSizeMake(265, 8000)]; 

    if ([[cellsToContainInterstitialImages allKeys] containsObject: [thisLine.lineID stringValue]]) { 

     UIImageView *interstitialImage = [[UIImageView alloc] init]; 
     NSNumber *cellTypeNumber = [cellsToContainInterstitialImages valueForKey: [thisLine.lineID stringValue]]; 
     kInterstitialCellType cellType = [cellTypeNumber intValue]; 

     if (cellType == kInterstitialCellTypeFirst) { 
      interstitialImage = [[UIImageView alloc] initWithImage: [UIImage imageNamed: @"man.png"]]; 
     } 
     else if (cellType == kInterstitialCellTypeSecond) { 
      interstitialImage = [[UIImageView alloc] initWithImage: [UIImage imageNamed: @"woman.png"]]; 
     } 
     else { 
      interstitialImage = [[UIImageView alloc] initWithImage: [UIImage imageNamed: @"child.png"]]; 
     } 

     [interstitialImage setFrame: CGRectMake(10, cell.lineLabel.frame.size.height + cell.actorLabel.frame.size.height + 10, 150, 150)]; 
     [cell addSubview: interstitialImage]; 
    } else { 
     UIImageView *interstitialImage = [[UIImageView alloc] init]; 
     [interstitialImage setImage: nil]; 
    } 

    return cell; 
} 

ответ

1

else ветвь кода не добавляет interstitialImage изображение в ячейку. Вы должны изменить свой код, чтобы добавить UIImageView в конструктор ячейки, так что в cellForRowAtIndexPath вам нужно будет установить изображение, а не добавлять subviews.

Добавьте UIImageView в ваш CustomCell, сделать его частным, и обеспечить свойство для cellForRowAtIndexPath использовать:

@interface CustomCell : UITableViewCell { 
    UIImageView *_interstitialImage; 
} 
@property (nonatomic,readonly) UIImageView *interstitialImage; 
@end 

@implementation CustomCell 
-(id)initWithStyle:(UITableViewCellStyle) style reuseIdentifier:(NSString*)reuseId { 
    if (self = [super initWithStyle:style reuseIdentifier:reuseId]) { 
     _interstitialImage = [[UIImageView alloc] init]; 
     [_interstitialImage setImage: nil]; 
     [_interstitialImage setFrame: CGRectMake(10, cell.lineLabel.frame.size.height + cell.actorLabel.frame.size.height + 10, 150, 150)]; 
     [cell addSubview: _interstitialImage]; 
    } 
    return self; 
} 
-(UIImageView*)interstitialImage { 
    return _interstitialImage; 
} 
@end 

Теперь ваш cellForRowAtIndexPath будет использовать cell.interstitialImage вместо выделения нового UIImageView всего времени. Это позволило бы избежать добавления изображения, несколько раз:

if ([[cellsToContainInterstitialImages allKeys] containsObject: [thisLine.lineID stringValue]]) { 
    NSNumber *cellTypeNumber = [cellsToContainInterstitialImages valueForKey: [thisLine.lineID stringValue]]; 
    kInterstitialCellType cellType = [cellTypeNumber intValue]; 

    if (cellType == kInterstitialCellTypeFirst) { 
     [cell.interstitialImage setImage:[UIImage imageNamed: @"man.png"]]; 
    } else if (cellType == kInterstitialCellTypeSecond) { 
     [cell.interstitialImage setImage:[UIImage imageNamed: @"woman.png"]]; 
    } else { 
     [cell.interstitialImage setImage: [UIImage imageNamed: @"child.png"]]; 
    } 
} else { 
    [cell.interstitialImage setImage: nil]; 
} 
+0

Извините, я не совсем понимаю. Разве мой «UIImageView» уже добавлен в конструктор? Это отдельный метод, за пределами 'cellForRowAtIndexPath'? Не могли бы вы немного объяснить ответ? – Luke

+0

Я получаю сообщение об ошибке «Дубликат интерфейса», если попытаюсь добавить частный раздел '@ interface'. Любая идея, почему это может быть? – Luke

+0

@ lukech Пример показывает, что вы можете сделать в фактическом объявлении своей пользовательской ячейки (конечно, сохраните ваши другие методы). Вы также можете сделать расширение класса, если хотите, но это вопрос вкуса. Если вы хотите пройти маршрут расширения, замените '@interface CustomCell: UITableViewCell' на' @interface CustomCell() '. – dasblinkenlight

0

Самым простым решением должно быть использование – tableView:willDisplayCell:forRowAtIndexPath: метод UITableViewDelegate протокола. Очистите ячейки в этом методе.

+0

Но как я узнаю, в какой ячейке я хотел оставить изображение, и от которого я хочу его удалить? Я не могу просто очистить каждую ячейку, иначе она удалит изображения из камер, в которых они должны находиться, не так ли? – Luke

+0

Если вы знаете, в каких ячейках должны быть ваши изображения, вы можете использовать параметр indexPath для их отслеживания и очистки ячеек, которые должны быть. – gsempe

+0

Как использовать 'willDisplayCell ...' проще, чем правильно получить изображения в 'cellForRow ...'? – rmaddy

0

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

В разделе else вы создаете образ фиктивного изображения и устанавливаете его изображение на nil. Этот код не делает то, что вы намеревались, - чтобы очистить существующее изображение.

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

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