Ios 为什么UICollectionView';用户触摸时UICollectionViewCell未高亮显示?

Ios 为什么UICollectionView';用户触摸时UICollectionViewCell未高亮显示?,ios,objective-c,uicollectionview,Ios,Objective C,Uicollectionview,我有一个由自定义UICollectionViewCell子类组成的UICollectionView。通过触发以下方法,该单元的显示正确,并对用户的触摸做出正确响应: - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 然而,我的理解是,当用户触摸电池时,它应该高亮显示(蓝色),然后当用户抬起手指时,高亮显示应该消失。这并没有发生。有

我有一个由自定义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;
}
@实现SplitCheckCollectionCell
-(id)initWithFrame:(CGRect)帧{
self=[super initWithFrame:frame];
如果(自我){
NSArray*ArrayOfView=[[NSBundle mainBundle]loadNibNamed:@“SplitCheckCollectionCell”所有者:自选项:nil];
如果([arrayOfViews计数]<1){
返回零;
}
如果(![[arrayOfViews objectAtIndex:0]是类的种类:[UICollectionViewCell类]]){
返回零;
}
self=[ArrayOfView对象索引:0];
}
回归自我;
}

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


详细信息见。

正如SAE所说,您必须在子类中自己完成。我刚才遇到的另一个障碍是,当点击一个单元格时,如果按住该单元格,它将接收高亮显示并重新绘制。然而,如果快速点击,重画就不会发生

我已经在故事板中创建了单元,集合视图默认勾选了“延迟内容接触”。我解开了这个,当手指触到屏幕时,它立即显示出来

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

-(void)setHighlighted:(BOOL)highlighted
{
    [super setHighlighted:highlighted];
    [self setNeedsDisplay];
}

通过将这些线添加到UICellView的设置中,可以获得要绘制的hilight

UIView* selectedBGView = [[UIView alloc] initWithFrame:self.bounds];
selectedBGView.backgroundColor = [UIColor redColor];
self.selectedBackgroundView = selectedBGView;
从“管理选择和突出显示的视觉状态”。。。
默认情况下,集合视图支持单个项目选择,并且可以配置为支持多个项目选择或完全禁用选择。集合视图检测其边界内的点击,并相应地高亮显示或选择相应的单元格。在大多数情况下,集合视图仅修改单元格的属性,以指示已选中或高亮显示该单元格它不会改变单元格的视觉外观,只有一个例外。如果单元格的selectedBackgroundView属性包含有效视图,则当单元格高亮显示或选中时,集合视图将显示该视图。

如果要更改视觉效果,可以在didHighlightItemAtIndexPath上将单元格设置为selected,并在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];
}

您应该实现两种委托方法:

- (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 ];
}

您可以尝试以下代码:

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


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

因此,在使用UICollectionViewDelegate方法的UICollectionView中:

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()
        }
    }
}

您需要实现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;
 }

我们可以在
collectionViewCell
上创建自己的高光和非高光效果,方法是添加和删除带有一些背景色的临时
视图,如下所示:

 -(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];
        }
    }

因此,在用户触摸时,突出显示状态不会自动变为是?或者它是否转到“是”,但视觉外观没有自动更改?它设置为“是”,但框架不会更改视觉外观。例如,您可以通过委托方法
collectionView:didHighlightItemAtIndexPath:
截取这可能是文档的新位置。感谢您提供有关“延迟内容接触”的提示!我也有同样的快速点击问题。和Ikegawa一样,感谢开发指南中关于“延迟内容接触”的提示。如果单元格的selectedBackgroundView属性包含有效视图,则当突出显示或选中单元格时,集合视图将显示该视图。是否有人可以回答他们为什么否决此答案?如果有一些反馈就好了,而不仅仅是一个不起作用的downvoteIt。您在单元格上设置的任何内容都将是暂时的,因为当您将其滚动到屏幕外时,该单元格可以重复使用。这对于默认集合视图单元格很好,但对于自定义UICollectionViewCell则不起作用。Xcode将显示一个错误。
 -(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];
        }
    }