UICollectionView - 如果选择了单元格,则不调用didDeselectItemAtIndexPath

zei*_*sen 32 objective-c ios uicollectionview

我做的第一件事是设置选定的单元格.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    cell.selected = YES;
    return cell;
}
Run Code Online (Sandbox Code Playgroud)

并且成功选择了单元格.如果用户触摸所选单元格,则应取消选择单元格并调用委托.但这绝不会发生.

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
}
Run Code Online (Sandbox Code Playgroud)

我知道如果我以编程方式设置选择,则不会调用委托.委托和数据源已设置.

但是,此委托被调用:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

如果我删除了cell.selected = YES一切正在工作.有没有人可以解释这种行为?

zei*_*sen 63

问题是,单元格被选中,但是UICollectionView对它没有任何了解.额外的呼吁UICollectionView解决了这个问题:

[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; 
Run Code Online (Sandbox Code Playgroud)

完整代码:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    cell.selected = YES;
    [collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
    return cell;
}
Run Code Online (Sandbox Code Playgroud)

我保留这个问题,以帮助可能面临同样问题的人.

  • 你好@zeiteisen.在我的情况下,当我选择一个单元格`didSelectItemAtIndexPath`被调用但是第二次单击单元格时它不会调用`didDselectItemAtIndexPath`.我想在两种方法中改变单元格的内容.我怎么能这样做? (7认同)

Rat*_*ker 25

我认为@zeiteisen提供的解决方案是一种解决方案.实际的事情在于选择模式.没有什么可以设置属性cell.selected.

UICollectionView名称allowsMultipleSelection和属性有两个属性allowsSelection.

allowsMultipleSelectionNO默认和allowsSelectionYES.

如果您只想选择一个单元格,那么初始化代码就像

yourCollectionView.allowsMultipleSelection = NO;
yourCollectionView.allowsSelection = YES; //this is set by default
Run Code Online (Sandbox Code Playgroud)

然后,设置将允许您一次只选择一个单元格,而不是更少.您必须至少选择一个单元格.didDeselectItemAtIndexPath除非您选择另一个单元格不会被调用.点击已经选中的UICollectionViewCell将不会取消选择.这是实施背后的政策.

如果要选择多个单元格,则代码@the初始化应如下所示:

yourCollectionView.allowsMultipleSelection = YES;
yourCollectionView.allowsSelection = YES; //this is set by default
Run Code Online (Sandbox Code Playgroud)

然后设置将允许选择多个单元格.此设置允许选择无或多个UICollectionViewCell.选择的单元格数量

0 <= number_selected_cell <= total_number_of_cell
Run Code Online (Sandbox Code Playgroud)

这是多小区选择背后的政策.

如果您打算使用上述任何一种,欢迎使用apple api而不会让您头疼,否则您必须找到一种方法,使用您自己的代码或apple的API来潜入您的目标.


Mea*_* S. 7

我遇到过同样的问题.我在桌面加载时预先选择了单元格但我不得不双击一个单元格以取消选择它.@zeiteisen的回答帮助了我.但是,我在Swift 3工作,所以我想我会在Swift中给出答案.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell

    if /*Test for Selection*/ {
        cell.isSelected = true
        collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .left)
    }        
    return cell
}
Run Code Online (Sandbox Code Playgroud)