1

Это следующий вопрос к моему previous one, и на этот раз у меня проблема с UIButton, которую я добавил в каждом UICollectionViewCell. Прежде чем погрузиться в проблему, позвольте мне рассказать обо всем, что у меня есть.Мессинг UIButton в каждом UICollectionViewCell в прокручивающемся диалоговом окне

Вот основная изношенном о том, как мой UICollectionView в Scrolling стиле киноленты в UITableView работы:

  • Создать нормальную UITableView с пользовательской UITableViewCell
  • Создание пользовательских UIView, который будет добавлен к contentView клетки
  • Пользовательский UIView будет содержать UICollectionView
  • Пользовательский UIView будет источником данных и делегатом для UICollectionView и управляет компоновкой потоков UICollectio NView
  • Использование пользовательских UICollectionViewCell для обработки вида сбора данных
  • Использования NSNotification уведомить UITableView главного контроллера, когда была выбрана вида ячейки сбора и загрузить подробный вид.

До сих пор я был в состоянии добавить UIButton в каждом UICollectionViewCell и когда я нажимаю на UIButton его изображение изменится на проверяемую отметку, но проблема возникает, когда я прокрутку вверх/вниз. Как только ячейка с отмеченной меткой UIButton выключена и снова прокручивается на экран, изображение UIButton начинает запутываться. Например, когда изображение UIButton в ячейке1 должно быть отмечено отметкой, но это не так. Вместо этого отметка появится в другой ячейке.

Здесь под мой соответствующий код:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    PostsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PostsCollectionViewCell" forIndexPath:indexPath]; 
    NSDictionary *cellData = [self.collectionData objectAtIndex:[indexPath row]]; 

    cell.postTextLabel.text = [cellData objectForKey:@"text"]; 
    cell.locationNameLabel.text = [cellData objectForKey:@"locationName"]; 

    // >>> Select Button <<< 
    UIButton *selectButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
    [selectButton setFrame:CGRectMake(110, 150, 20, 20)]; 
    [selectButton setImage:[UIImage imageNamed:@"uncheckedDot.png"] forState:UIControlStateNormal]; 
    [selectButton setImage:[UIImage imageNamed:@"checkedDot.png"] forState:UIControlStateSelected]; 
    [cell.contentView addSubview:selectButton]; 
    [selectButton addTarget:self 
        action:@selector(buttonPressed:) 
     forControlEvents:UIControlEventTouchUpInside]; 
    // >>> End Select Button <<<< 

    return cell; 
} 

// >>> Select Button Method <<< 
-(void) buttonPressed:(UIButton *)sender 
{ 
    if([sender isSelected]){ 
     //... 
     [sender setSelected:NO]; 
    } else { 
     //... 
     [sender setSelected:YES]; 
    } 
} 

Любая помощь будет принята с благодарностью! Заранее спасибо.

enter image description here

+1

Я знаю, что вы преодолели проблему, но я хотел бы обратить ваше внимание на другой подход к повторному использованию ячеек: кроме -collectionView: cellForItemAtIndexPath: есть метод в UICollectionViewCell/UITableViewCell, который может быть полезен для удаления вашего ячейки до состояния по умолчанию, когда они переходят к повторному использованию. А именно, - (void) prepareForReuse - один. Об этом можно узнать в центре dev (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/occ/instm/UITableViewCell/prepareForReuse). –

ответ

2

Человек, вы должны знать, что клетки (как для UITableView и UICollectionView) повторно используются через повторное использование дека под капотом UIKit и не обязаны сохранять свое состояние в соответствии с точки зрения их положения в представление таблицы или представление коллекции. Что вам нужно сделать, так это убедиться, что возвращаемое значение dequeueReusableCellWithReuseIdentifier: затем правильно инициализировано (или в вашем случае повторно инициализировано) в соответствии с состоянием вашей модели данных. В принципе, вам нужно сохранить состояние ваших «галочек» (или «флажков», что у вас есть) в массиве или любой другой структуре данных. Затем, когда вы вызываете dequeueReusableCellWithReuseIdentifier:, вы должны применить это сохраненное состояние к возвращаемому значению (ячейке, которую вы собираетесь вернуть для коллекции), которое вы только что получили. Надеюсь, это объясняется достаточно хорошо. Удачи.

2

Поддержание в источнике данных, который следует выбрать, добавив ключ для каждого источника данных dict.Например: @ "IsSelected"

Тогда в cellForRowAtIndexPath:

if ([[cellData valueForKey:@"isSelected"] boolValue]) { 
    [selectButton setSelected:NO]; 
} else { 
    [selectButton setSelected:YES]; 
} 

и в вашем -(void) buttonPressed:(UIButton *)sender Метод:

CGPoint point = [self.collectionView convertPoint:CGPointZero fromView:sender]; 
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point]; 
NSDictionary *cellData = [self.collectionData objectAtIndex:[indexPath row]]; 

if ([[cellData valueForKey:@"isSelected"] boolValue]) { 
    [cellData setValue:@"false" forKey:@"isSelected"]; 
} else { 
    [cellData setValue:@"true" forKey:@"isSelected"]; 
} 

[self.framesCollectionView reloadItemsAtIndexPaths:@[indexPath]]; 

И

В вашем cellForRowAtIndexPath установлен тег для UIButton. Затем перед добавлением UIButton в качестве подчиненного элемента в contentView ячейки проверьте, существует ли представление с этим тегом. Если ячейка была повторно использована, просто используйте уже существующую кнопку.