【发布时间】:2017-01-20 04:50:18
【问题描述】:
我试图创建一个包含单元格列表的集合视图。当用户点击一个按钮时,它会随机选择一个单元格。
现在假设只有 10 个单元格。即numberOfItemsInSection委托返回10。
视图控制器是 collectionView 的数据源。集合视图称为myCollectionView。它有一个属性叫selectedIndexPath
所以视图控制器:
@interface ViewController () < UICollectionViewDataSource>
@property (nonatomic, strong) NSIndexPath * selectedIndexPath;
@property (strong, nonatomic) IBOutlet UICollectionView *myCollectionView;
@end
这是我在视图控制器中的随机选择代码:
-(void)chooseRandom{
NSInteger randomShadeIndex = arc4random_uniform((uint32_t)10);
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:randomShadeIndex inSection:0];
self.selectedIndexPath = indexPath;
[self.myCollectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
}
这是我的视图控制器中的cellForItemAtIndexPath
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
MyCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];
cell.selected = self.selectedIndexPath == indexPath;
return cell;
}
这是MyCell 中的setSelected: 方法:
- (void)setSelected:(BOOL)selected{
[super setSelected:selected];
if (selected){
self.backgroundColor = [UIColor redColor];
} else {
self.backgroundColor = [UIColor greenColor];
}
}
所以现在当我通过按下按钮拨打chooseRandom 时。如果要选择的随机单元格不可见(不在当前屏幕中),那么很有可能它最终不会在 selectItemAtIndexPath: 期间调用 setSelected:YES。(或者它被调用但设置了单元格。选择为NO 而不是YES)。这意味着生成的屏幕没有选择任何单元格。
有趣的是,当我尝试触摸屏幕时(不选择任何单元格)。它将在要选择的单元格上调用setSelected:。所以我认为selectItemAtIndexPath: 被窃听了。
只有当界面生成器中的prefetching enabled 设置为启用时才会发生这种情况。(这是 ios 10 的默认设置)。
我已经尝试了以下方法来解决这个问题,但它们都不起作用:
在
chooseRandom末尾添加[self.myCollectionView cellForItemAtIndexPath:indexPath].selected = YES;。将
scrollToItemAtIndexPath与方法1一起使用,而不是selectItemAtIndexPath:
我认为要么这是一个错误,要么我完全忽略了某些东西。我已经坚持了几个小时,无法弄清楚为什么。现在我认为这很可能是设置了prefetching enabled 的selectItemAtIndexPath 的错误。
如果您遇到同样的问题,请帮助我并告诉我。谢谢!
编辑: 不知道是否同样的问题。 this link has similar issue but with deselect
【问题讨论】:
-
尝试调用 scrollToItemAtIndexPath: 和下一行调用 selectItemAtIndexPath:
-
@jayarj 我试过了,但没有用。我也认为它应该在 selectItemAtIndexPath 中滚动。
-
启用预取时,集合视图委托上的 collectionView(:cellForItemAt:) 方法会在需要单元格时提前调用。为避免视觉外观不一致,请使用 collectionView(:willDisplay:forItemAt:) 委托方法更新单元格以反映视觉状态,例如选择。
-
docs 中的注释说如果你使用 prefetchingEnabled 你必须使用
willDisplayCell来更新你的单元格外观(例如选择状态)
标签: ios objective-c uicollectionview uicollectionviewcell ios10