启用Ios10 UICollectionView预取会导致selectItemAtIndexPath行为不正确

时间:2017-01-20 04:50:19

标签: ios objective-c uicollectionview uicollectionviewcell ios10

我正在尝试使用单元格列表创建集合视图。当用户点击按钮时,它将随机选择一个单元格。

现在假设只有10个细胞。即numberOfItemsInSection代表返回10。 视图控制器是collectionView的数据源。集合视图称为myCollectionView。它有一个名为selectedIndexPath

的属性

所以ViewController:

@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;
}

这是[{1}}中的setSelected:方法:

MyCell

现在,当我按下按钮时调用- (void)setSelected:(BOOL)selected{ [super setSelected:selected]; if (selected){ self.backgroundColor = [UIColor redColor]; } else { self.backgroundColor = [UIColor greenColor]; } } 。如果要选择的随机单元格不可见(不在当前屏幕中),那么它很可能不会在chooseRandom期间调用setSelected:YES。(或者它被调用但是将cell.selected设置为selectItemAtIndexPath:而不是NO)。这意味着生成的屏幕没有选择单元格。

有趣的是,当我尝试触摸屏幕时(没有选择任何单元格)。它将调用要选择的单元格上的YES。所以我认为setSelected:被窃听了。

只有在界面构建器中的selectItemAtIndexPath:设置为启用时才会发生这种情况。(这是ios 10的默认设置)。

我尝试过以下方法来解决这个问题,但没有一个能够解决这个问题:

  1. prefetching enabled末尾添加[self.myCollectionView cellForItemAtIndexPath:indexPath].selected = YES;

  2. 使用chooseRandom和方法1代替scrollToItemAtIndexPath

  3. 我认为这是一个错误,或者我完全忽略了一些东西。我已经被困在这几个小时,无法弄清楚原因。现在我认为设置selectItemAtIndexPath:的{​​{1}}很可能是一个错误。

    如果您遇到同样的问题,请帮助我并告诉我。谢谢!

    编辑: 不确定是否有同样的问题。 this link has similar issue but with deselect

2 个答案:

答案 0 :(得分:0)

UICollectionView就像UITableView一样,缓存其单元格。这意味着,如果您有100个单元格,并且只有10个单元格可见,它将只创建10个单元格并在滚动时重复使用它们,在滚动时设置可见单元格的模型/数据,重用不可用的单元格再次可见(以节省内存)。因此,您无法选择不可见的单元格的原因可能是因为它尚未创建。

答案 1 :(得分:0)

如果有帮助,请检查一下

可以下载示例项目

https://www.dropbox.com/s/oeo9p1h3e8xfpfj/CollectionView.zip?dl=0

-(void)chooseRandom{
   NSInteger randomShadeIndex = arc4random_uniform((uint32_t)50);
   NSLog(@"%ld",(long)randomShadeIndex);
   NSIndexPath *indexPath = [NSIndexPath indexPathForItem:randomShadeIndex inSection:0];
   self.selectedIndexPath = indexPath;

   [self.myCollectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:true];
  [_myCollectionView reloadData]; 
}