41

我有一个由自定义 UICollectionViewCell 子类组成的 UICollectionView。单元格正确显示,并通过触发此方法正确响应用户的触摸:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

但是,我的理解是,当用户触摸单元格时,它应该突出显示(蓝色),然后当用户抬起手指时突出显示应该消失。这没有发生。关于为什么的任何想法?

以下是一些相关代码:

在 UICollectionView 的数据源中:

@implementation SplitCheckViewCollection

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellIdentifier = @"ReceiptCellIdentifier";
    SplitCheckCollectionCell *cell = (SplitCheckCollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    cell.cellName.text = [NSString stringWithFormat:@"%@%i",@"#",indexPath.row+1];

    return cell;
}

在 UICollectionViewCell 的实现中:

@implementation SplitCheckCollectionCell

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"SplitCheckCollectionCell" owner:self options:nil];

        if ([arrayOfViews count] < 1) {
            return nil;
        }

        if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
            return nil;
        }

        self = [arrayOfViews objectAtIndex:0];    
    }
    return self;
}
4

9 回答 9

34

该类仅告诉您高亮状态,但不会更改视觉外观。您必须通过例如更改单元格的背景以编程方式执行此操作。

CollectionView 编程指南中描述了详细信息。

于 2013-01-31T23:33:53.967 回答
33

正如 SAE 所说,你必须在子类中自己做。我刚刚遇到的另一个问题是,当点击一个单元格时,如果按下并按住该单元格,它将接收高亮并重绘。但是,如果快速点击,重绘就不会发生。

我在情节提要中创建了单元格,并且集合视图默认勾选了“延迟内容触摸”。我取消勾选它,它立即显示手指触摸屏幕。

我正在使用一个自定义绘制例程来检查 isHighlighted 值。您还需要在自定义单元格中覆盖 setHighlighted,如下所示,否则绘制例程永远不会被调用。

-(void)setHighlighted:(BOOL)highlighted
{
    [super setHighlighted:highlighted];
    [self setNeedsDisplay];
}
于 2013-02-01T23:43:17.620 回答
32

您应该实现 2 个委托方法:

- (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)colView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath;

用动画突出显示集合视图单元格的完整代码:

- (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
     UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
     //set color with animation
    [UIView animateWithDuration:0.1
                      delay:0
                    options:(UIViewAnimationOptionAllowUserInteraction)
                 animations:^{
                     [cell setBackgroundColor:[UIColor colorWithRed:232/255.0f green:232/255.0f blue:232/255.0f alpha:1]];
                 }
                 completion:nil];
 }

- (void)collectionView:(UICollectionView *)colView  didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
    //set color with animation
    [UIView animateWithDuration:0.1
                      delay:0
                    options:(UIViewAnimationOptionAllowUserInteraction)
                 animations:^{
                     [cell setBackgroundColor:[UIColor clearColor]];
                 }
                 completion:nil ];
}
于 2014-08-12T08:06:39.793 回答
8

如果要在触摸和释放触摸时具有突出显示和取消突出显示效果,则需要实现UICollectionViewDataSource

这是示例代码

#pragma mark - UICollectionView Datasource

 - (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
 UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
 cell.contentView.backgroundColor = [UIColor colorWithRed:235/255.0f green:236/255.0f blue:237/255.0f alpha:.5];
 }

 - (void)collectionView:(UICollectionView *)colView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath {
 UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
 cell.contentView.backgroundColor = nil;
 }
于 2015-07-09T02:55:39.853 回答
7

您可以通过将这些线添加到 UICellView 的设置中来获得要绘制的亮点。

UIView* selectedBGView = [[UIView alloc] initWithFrame:self.bounds];
selectedBGView.backgroundColor = [UIColor redColor];
self.selectedBackgroundView = selectedBGView;

来自“管理选择和突出显示的视觉状态”...集合视图默认支持单项选择,并且可以配置为支持多项选择或完全禁用选择。集合视图检测其边界内的点击并相应地突出显示或选择相应的单元格。在大多数情况下,collection view 只修改单元格的属性以表明它被选中或突出显示;它不会改变细胞的视觉外观,但有一个例外。如果单元格的 selectedBackgroundView 属性包含有效视图,则集合视图会在单元格突出显示或选中时显示该视图。

于 2013-10-28T18:46:50.133 回答
4

正如 SAE 指出的那样,您必须在突出显示的单元格中手动执行此操作。我发现最简单的方法是使用 tableview didHighlightRowAtIndexPath 和 didUnhighlightRowAtIndexPath 方法,它们在 UICollectionCell 实例中设置一个布尔“突出显示”,然后在子类 UICollectionCell 类中覆盖该属性。这样做的美妙之处在于动画已经为您准备好了。你也可以在 UITableView/UITableViewCell 的情况下做同样的事情。

所以在你的 UICollectionView 中使用 UICollectionViewDelegate 方法:

func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {
    collectionView.selectItemAtIndexPath(indexPath, animated: true, scrollPosition: UICollectionViewScrollPosition.None)
}

func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {
    collectionView.deselectItemAtIndexPath(indexPath, animated: true)
}

然后在你的 UICollectionViewCell 子类中添加:

override var highlighted:Bool{
    didSet{
        println("Highlighted is set \(highlighted)")
        if(highlighted == true){
            self.backgroundColor = UIColor.redColor()
        }else{
            self.backgroundColor = UIColor.blueColor()
        }
    }
}
于 2015-07-02T14:18:43.320 回答
1

你可以试试这段代码:

- (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor blueColor];
}

- (void)collectionView:(UICollectionView *)colView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = nil;
}
于 2015-07-02T10:33:40.880 回答
1

collectionViewCell我们可以通过添加和删除具有一些背景颜色的临时对象来创建自己的突出显示和取消突出显示效果view,如下所示:

 -(void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
    
    {
        
         UICollectionViewCell *collectionViewCell = (UICollectionViewCell *)  
                            [collectionView cellForItemAtIndexPath:indexPath];
           
     UIView *tapHighlightView = (UIView*)[collectionViewCell.contentView 
                                  viewWithTag:10];
    
     if (!tapHighlightView) {
    
                tapHighlightView = [[UIView alloc] 
                        initWithFrame:collectionViewCell.contentView.frame];
                tapHighlightView.backgroundColor =[UIColor blackColor alpha:0.4];
                tapHighlightView.tag = 10;
                [collectionViewCell.contentView addSubview:tapHighlightView];
            }
    }
    
    -(void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath{
    
        UICollectionViewCell *collectionViewCell = (UICollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
        UIView *tapHighlightView = (UIView*)[collectionViewCell.contentView viewWithTag:10];
        if (tapHighlightView != nil) {
            [tapHighlightView removeFromSuperview];
        }
    }
于 2016-08-12T05:45:20.263 回答
0

如果要更改视觉效果,可以在 didHighlightItemAtIndexPath 上将单元格设置为选中,然后在 didHighlightItemAtIndexPath 上取消选择,如下所示:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    [collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:NO];
}

- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    [collectionView deselectItemAtIndexPath:indexPath animated:YES];
}
于 2014-05-14T13:45:50.820 回答