在UICollectionView
中,我有一个自定义UICollectionViewCellClass
,其中 prepareForReuse 会被默认格式化员工覆盖。
我有一个NSMutableArray
来自 didSelectItemAtIndexPath:的NSIndexPaths
。
在 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 :(得分: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;
答案 1 :(得分:1)
我最近遇到了与我的应用完全相同的问题。 UICollectionViewCell选择在iOS 8.3之前正常工作,随后我开始看到一些奇怪的行为。未实际选择的单元格将显示为选中状态,其他单元格似乎无法选择。
我在UICollectionViewCell子类上实现了自定义setSelected
和prepareForResuse
方法:
-(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。遵循这一建议解决了我的问题。
答案 2 :(得分:0)
在iOS 10中,我发现在启用预取时,以编程方式清除启用了多选的UICollectionView是错误的。当然,iOS 10中默认启用预取。