UICollection代理方法didSelectIte…

来源:互联网 发布:杭州java周末培训班 编辑:程序博客网 时间:2024/05/25 12:22

需求:

  • 点击一个cell, 会调用didSelectItemAtIndexPath:方法,然后点击另外一个cell,首先会调用didDeselectItemAtIndexPath:这个方法,然后在调用didSelectItemAtIndexPath:方法

问题:

  • 当然实现这个需求非常容易,但是当你在didSelectItemAtIndexPath中调用reloadItemsAtIndexPaths或者reloadData这两个方法(经常在这个方法中我们用来修改模型数据,并使用这两个方法来刷新cell上面的显示),来刷新cell上面的数据的时候,就会发现,didDeselectItemAtIndexPath这个方法不会调用了.

原因

  • 我稍微分析了下原因.在调用reloadItemsAtIndexPaths或者reloadData,系统内部是会调用数据源方法cellForItemAtIndexPath:,而在这个方法里面,cell的selected属性又重新被初始化为NO了,所以此时cell的是处于非选中状态的,自然就不会调用didDeselectItemAtIndexPath:这个方法来取消选中.

解决方法分析

  • 找到了原因,那么我们开始想办法.
  • 我们也许可以在cellForItemAtIndexPath:这个方法中手动来设置cell的状态(这里设置cell的状态就是cell的最终状态,因为这个方法最后调用的).我们马上就可以想到有2个方法也许可以修改cell的selected属性

    • 第一种: cell的selected属性:让我们看看官方的解释

        This property manages the selection state of the cell only. The default value of this property is NO, which indicates that the cell is not selected.You typically do not set the value of this property directly. Changing the value of this property programmatically does not change the appearance of the cell. The preferred way to select the cell and highlight it is to use the selection methods of the collection view object.这个属性仅仅是用于管理cell的选中状态.默认这个值为NO.意味着cell默认情况下是没有被选中的.通常情况下,不要直接设置这个属性.使用代码来改变这个值并不会改变cell的外观.选中cell,并让cell显示高亮状态最好的方法就是调用UICollectionView相关selection方法来实现.
    • 官方也建议我们不要直接来设置,直接设置的话有可能并不会达到你想要的效果.经过我的测试,直接设置确实没有作用.同学们可以自己去试一下
    • 第二种: -[UICollectionViewselectItemAtIndexPath:animated:scrollPosition:]
    • 这个方法可能就是苹果官方建议的通过UICollectionView的对象方法来设置cell的选中状态.

      • 还是让我们看看官方的解释

        If the allowsSelection property is NO, calling this method has no effect. If there is an existing selection with a different index path and the allowsMultipleSelection property is NO, calling this method replaces the previous selection.This method does not cause any selection-related delegate methods to be called.如果allowsSelection属性为NO, 调用这个方法没有任何效果.如果有任何另外一个已经被选中cell(官方的说明是另外一个索引, 同一个意思)并且allowsMultipleSelection(允许多项选择)这个属性为NO, 那么调用这个方法会取代那个cell的选中状态.也就是说当 allowsSelection = YES (默认就是YES), allowsMultipleSelection = NO(这个也是默认设置), 调用这个方法就会取消上一个cell的选中状态,然后让当前的cell选中.
    • 看完官方的解释,相信大家都明白了,刚好就是我们需要的属性

最终解决方案

  • 综上所述, 如果你在didSelectItemAtIndexPath:didDeselectItemAtIndexPath这两个方法中调用了reloadItemsAtIndexPaths或者reloadData这两个方法来刷新cell上面显示的数据,但是发现,didDeselectItemAtIndexPath这个代理方法并没有调用,你只需要做出如下的配置即可

       // 这两个属性都是默认配置的,如果你没有修改的话,就不用写   allowsSelection = YES;   allowsMultipleSelection = NO;   - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{// 需要配置的代码[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];}
0 0
原创粉丝点击