3

UICollectionView中,我有一个自定义UICollectionViewCellClass,其中prepareForReuse被默认格式化工作人员覆盖。重复使用单元格UICollectionView - 某些单元格未被选中

我有一个NSMutableArray包含NSIndexPathsdidSelectItemAtIndexPath:

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?你在哪里创建它?如果[self isSelectedIndexPath:indexPath]返回false,我认为你还需要一个“else”部分来说明单元格应该是什么样子。 – rdelmar 2013-04-06 15:59:57

+0

它是一种检查indexPath是否包含在NSIndexPaths的NSMutableArray中的方法。当indexPath等于数组中的某一个时,它总是返回false。 – ragnarok 2013-04-06 16:36:53

+0

好的,你是否在if语句中添加了“else”部分以查看是否有帮助。由于单元重用,如果if语句为false,则需要将单元格的外观设置为未选中状态。 – rdelmar 2013-04-06 16:45:25

回答

2

我发现了两个问题。 prepareForReuse方法似乎是搞砸了,所以我刚删除它。但是,主要的问题是你正在实现的方式isSelectedIndexPath :.只要您在循环查找项目时发现第一个选定项目,它就会返回YES并退出循环。你想要做什么,只是检查indexPath包含在selectedCellIndexPaths数组中:

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

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

或者,如果你喜欢使用更简洁的语法,你可以替换的if-else块:

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

即使这些更改仍存在问题。但是非常感谢您的耐心和坚持。 – ragnarok 2013-04-06 21:41:21

+0

对不起,我想删除prepareForReuse。现在一切都很精彩。再次感谢耐心和坚持。 – ragnarok 2013-04-06 21:49:10

+1

Just:'return [selectedCellIndexPaths containsObject:indexPath];' – k06a 2013-10-02 17:27:50

1

我最近面对与我的应用程序完全相同的问题。 UICollectionViewCell选择在iOS 8.3之前正常工作,随后我开始看到一些奇怪的行为。实际上未选中的单元格会显示为已选中,其他单元格似乎无法选中。

我对一个子类UICollectionViewCell实现为这样的两个定制setSelectedprepareForResuse方法:

-(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声明默认实现什么都不做,但他们也建议应该调用super。按照这个建议解决了我的问题。

0

在iOS 10中,我发现在启用预取时,以编程方式清除启用了多选的UICollectionView是错误的。当然,默认情况下预取在iOS 10中是打开的。