3

В UICollectionView у меня есть пользовательский UICollectionViewCellClass, где prepareForReuse переопределяется для сотрудников по умолчанию.Повторное использование ячеек UICollectionView - некоторые ячейки не выбраны

У меня есть NSMutableArray, содержащий NSIndexPaths от didSelectItemAtIndexPath:.

В cellForItemAtIndexPath: Я переформатировал выделенные ячейки так, чтобы они были выбраны.

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 

ButtonCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ButtonCell" forIndexPath:indexPath]; 

NSString *title = self.ingredientsBook.names[indexPath.item]; 

cell.label.text = title; 

if ([self isSelectedIndexPath:indexPath]){ 

    cell.backgroundColor = [UIColor whiteColor]; 
    cell.label.textColor = [UIColor blueColor]; 
} 
return cell; 

} 

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ 

self.searchButton.enabled = YES; 

ButtonCell *cell = (ButtonCell *)[collectionView cellForItemAtIndexPath:indexPath]; 
[selectedCellIndexPaths addObject:indexPath]; 
NSLog(@"%@", selectedCellIndexPaths); 
cell.backgroundColor = [UIColor whiteColor]; 
cell.label.textColor = [UIColor blueColor]; 

NSString *name = self.ingredientsBook.names[indexPath.item]; 
[self.selectedIngredientNames addObject:name]; 


} 

Проблема в том, что при нажатии первой ячейки невозможно выбрать 16-й или 17-й. Или, если я коснусь первых трех, невозможно выбрать три последних. didSelectItemAtIndexPath не называется.

Я чувствую, что это должно быть что-то очень простое, но я не вижу его прямо сейчас.

Я попытался поместить NSLogs в shouldSelectItemAtIndexPath, чтобы понять, был вызван этот метод и метод вообще не вызван. Это происходит, когда между выбранным и проблемным существует расстояние 16 ячеек.

Вот другие методы источника данных и isSelectedIndexPath:

-(BOOL)isSelectedIndexPath:(NSIndexPath *)indexPath{ 

for (NSIndexPath *test in selectedCellIndexPaths){ 
    if (test == indexPath){ 
     return YES; 
    } 
} 

return NO; 
} 

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ 

return [self.ingredientsBook.names count]; 
} 

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ 

return 1; 
} 

-(BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath{ 

NSLog(@"%@", indexPath); 

return YES; 
} 


-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{ 

self.searchButton.enabled = ([[collectionView indexPathsForSelectedItems] count] > 0); 

ButtonCell *cell = (ButtonCell *)[collectionView cellForItemAtIndexPath:indexPath]; 
cell.backgroundColor = [UIColor blackColor]; 
cell.label.textColor = [UIColor whiteColor]; 

[selectedCellIndexPaths removeObject:indexPath]; 
NSString *name = self.ingredientsBook.names[indexPath.item]; 
[self.selectedIngredientNames removeObject:name]; 



} 
+0

Что такое isSelectedIndexPath? Где вы это создаете? Я думаю, вам также нужна часть «else», чтобы сказать, как выглядят ячейки, если [self isSelectedIndexPath: indexPath] возвращает false. – rdelmar

+0

это метод, который проверяет, содержится ли indexPath в NSMutableArray из NSIndexPaths. он всегда возвращает false отдельно, когда indexPath равен одному из выбранных в массиве. – ragnarok

+0

Хорошо, вы добавили часть «else» в оператор if, чтобы узнать, помогает ли это. Из-за повторного использования ячеек вам нужно установить внешний вид ячейки в невыбранное состояние, если это утверждение if false. – rdelmar

ответ

2

я нашел две проблемы. Метод prepareForReuse, казалось, искажал вещи, поэтому я просто удалил его. Основная проблема, однако, заключалась в том, как вы реализовали isSelectedIndexPath :. Как только он находит первый выбранный элемент при прохождении элементов, он возвращает YES и выходит из цикла. То, что вы хотите сделать, это просто проверить, если indexPath содержится в массиве selectedCellIndexPaths:

-(BOOL)isSelectedIndexPath:(NSIndexPath *)indexPath{ 

    if ([selectedCellIndexPaths containsObject:indexPath]) { 
     return YES; 
    }else{ 
     return NO; 
    } 
} 

Или, если вы предпочитаете использовать более лаконичный синтаксис, вы можете заменить если-нибудь блок с:

return ([selectedCellIndexPaths containsObject:indexPath])? YES : NO; 
+0

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

+0

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

+1

Just: 'return [selectedCellIndexPaths containsObject: indexPath];' – k06a

1

Недавно я столкнулся с тем же вопросом с моим приложением. Выбор UICollectionViewCell работал правильно до iOS 8.3, впоследствии я начал видеть странное поведение. Ячейки, которые на самом деле не были выбраны, будут отобраны, другие ячейки, казалось бы, случайно не могут быть выбраны.

я имел как пользовательские setSelected и prepareForResuse методы, реализованную на подклассе UICollectionViewCell как таковые:

-(void)setSelected:(BOOL)selected 
{ 
    [super setSelected:selected]; 

    if (selected) 
    { 
     [[self selectedIndicator] setHidden:NO]; 
    } 
    else 
    { 
     [[self selectedIndicator] setHidden:YES]; 
    } 
} 

-(void)prepareForReuse 
{ 
    [[self imageView] setImage:nil]; 
} 

Метод prepareForReuse просто сбросить вид изображения в пользовательской ячейке.

В моем методе prepareForReuse я не звонил [super prepareForReuse] (который в соответствии с документацией ничего не делает по умолчанию). Когда я добавил вызов [super prepareForReuse], весь выбор работал так, как предполагалось. Хотя Apple заявляет, что реализация по умолчанию ничего не делает, они также рекомендуют вызывать супер. Следуя этой рекомендации, я решил проблему.

0

В iOS 10 я обнаружил, что программная очистка UICollectionView с включенным множественным выбором была ошибкой, когда была включена предварительная выборка.И, конечно, предварительная выборка включена по умолчанию в iOS 10.

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