【问题标题】:Cell stops responding to selection after pan平移后单元格停止响应选择
【发布时间】:2014-06-11 16:25:04
【问题描述】:

问题:

完成平移手势后,启动点击下方的单元格不再响应选择。 didSelectItemAtIndexPath 将在点击其他单元格时触发,而不是在平移手势下的单元格。

如何让该单元格再次响应触摸输入?或者,如何检查该单元格是否因响应事件而卡住?

背景:

  • 我有一个带有一堆单元格的 UICollectionView。在此集合视图中点击一个单元格会触发 didSelectItemAtIndexPath。
  • 集合视图具有平移手势识别器。平移创建视图的图像并将其在屏幕上平移。在平移手势期间,集合视图位于其他视图下方。

理论:

由于平移,选择可能永远不会完成。也许 UI 中有一个触摸事件。如果我能清除它,也许细胞会再次响应。我尝试设置[panHandler setCancelsTouchesInView:YES],但没有任何改变。

更新 1:

在 cmets 中,有几个人建议图像可能会悬空并挡住触摸。在传递给animateWithDuration 的完成块中,我有以下几行:

[self.regionScreenshot removeFromSuperview];
self.regionScreenshot = nil;

我验证了这些行已被执行。

另一个让我相信这不是问题的因素是,在所有单元格中,只有那些用于拖动的单元格受到影响。周围的细胞仍然有反应。

更新 2:代码和 Gif

- (IBAction)handlePanFrom:(UIPanGestureRecognizer*)recognizer
{
    CGPoint translation = [recognizer translationInView:recognizer.view];
    float transparencyLevel = 0.85;

    if (recognizer.state == UIGestureRecognizerStateBegan)
    {
        SFCYRegion* centerRegion = self.region;

        //North
        if (centerRegion.regionToNorth != nil)
        {
            self.region = centerRegion.regionToNorth;
            [self reloadRegion];
            self.regionToNorthScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToNorthScreenshot = [[UIView alloc] init];
            self.regionToNorthScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToNorthScreenshot];
        self.regionToNorthScreenshot.alpha = transparencyLevel;
        self.regionToNorthScreenshot.frame = northFrame;

        //East
        if (centerRegion.regionToEast != nil)
        {
            self.region = centerRegion.regionToEast;
            [self reloadRegion];
            self.regionToEastScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToEastScreenshot = [[UIView alloc] init];
            self.regionToEastScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToEastScreenshot];
        self.regionToEastScreenshot.alpha = transparencyLevel;
        self.regionToEastScreenshot.frame = eastFrame;

        //South
        if (centerRegion.regionToSouth != nil)
        {
            self.region = centerRegion.regionToSouth;
            [self reloadRegion];
            self.regionToSouthScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToSouthScreenshot = [[UIView alloc] init];
            self.regionToSouthScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToSouthScreenshot];
        self.regionToSouthScreenshot.alpha = transparencyLevel;
        self.regionToSouthScreenshot.frame = southFrame;

        //West
        if (centerRegion.regionToWest != nil)
        {
            self.region = centerRegion.regionToWest;
            [self reloadRegion];
            self.regionToWestScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToWestScreenshot = [[UIView alloc] init];
            self.regionToWestScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToWestScreenshot];
        self.regionToWestScreenshot.alpha = transparencyLevel;
        self.regionToWestScreenshot.frame = westFrame;

        //Northeast
        if (centerRegion.regionToNorth != nil && centerRegion.regionToNorth.regionToEast != nil)
        {
            self.region = centerRegion.regionToNorth.regionToEast;
            [self reloadRegion];
            self.regionToNortheastScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToNortheastScreenshot = [[UIView alloc] init];
            self.regionToNortheastScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToNortheastScreenshot];
        self.regionToNortheastScreenshot.alpha = transparencyLevel;
        self.regionToNortheastScreenshot.frame = northeastFrame;

        //Southeast
        if (centerRegion.regionToSouth != nil && centerRegion.regionToSouth.regionToEast != nil)
        {
            self.region = centerRegion.regionToSouth.regionToEast;
            [self reloadRegion];
            self.regionToSoutheastScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToSoutheastScreenshot = [[UIView alloc] init];
            self.regionToSoutheastScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToSoutheastScreenshot];
        self.regionToSoutheastScreenshot.alpha = transparencyLevel;
        self.regionToSoutheastScreenshot.frame = southeastFrame;

        //Southwest
        if (centerRegion.regionToSouth != nil && centerRegion.regionToSouth.regionToWest != nil)
        {
            self.region = centerRegion.regionToSouth.regionToWest;
            [self reloadRegion];
            self.regionToSouthwestScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToSouthwestScreenshot = [[UIView alloc] init];
            self.regionToSouthwestScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToSouthwestScreenshot];
        self.regionToSouthwestScreenshot.alpha = transparencyLevel;
        self.regionToSouthwestScreenshot.frame = southwestFrame;

        //Northwest
        if (centerRegion.regionToNorth != nil && centerRegion.regionToNorth.regionToWest != nil)
        {
            self.region = centerRegion.regionToNorth.regionToWest;
            [self reloadRegion];
            self.regionToNorthwestScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        }
        else
        {
            self.regionToNorthwestScreenshot = [[UIView alloc] init];
            self.regionToNorthwestScreenshot.backgroundColor = [UIColor darkGrayColor];
        }
        [self.view.superview addSubview:self.regionToNorthwestScreenshot];
        self.regionToNorthwestScreenshot.alpha = transparencyLevel;
        self.regionToNorthwestScreenshot.frame = northwestFrame;



        //Self
        self.region = centerRegion;
        [self reloadRegion];
        self.regionScreenshot = [self.collectionView snapshotViewAfterScreenUpdates:YES];
        self.regionScreenshot.frame = mainFrame;
        self.regionScreenshot.center = mainFrameCenter;
        [self.view.superview addSubview:self.regionScreenshot];

        self.collectionView.alpha = 0;
    }
    else if (recognizer.state == UIGestureRecognizerStateChanged)
    {
        //Track the movement:
        self.regionScreenshot.center = [self movePoint:mainFrameCenter
                                                   byX:translation.x andY:translation.y];
        self.regionToNorthScreenshot.center = [self movePoint:northFrameCenter
                                                          byX:translation.x andY:translation.y];
        self.regionToEastScreenshot.center = [self movePoint:eastFrameCenter
                                                         byX:translation.x andY:translation.y];
        self.regionToSouthScreenshot.center = [self movePoint:southFrameCenter
                                                          byX:translation.x andY:translation.y];
        self.regionToWestScreenshot.center = [self movePoint:westFrameCenter byX:translation.x andY:translation.y];
        self.regionToNortheastScreenshot.center = [self movePoint:northeastFrameCenter
                                                              byX:translation.x andY:translation.y];
        self.regionToSoutheastScreenshot.center = [self movePoint:southeastFrameCenter
                                                              byX:translation.x andY:translation.y];
        self.regionToSouthwestScreenshot.center = [self movePoint:southwestFrameCenter
                                                              byX:translation.x andY:translation.y];
        self.regionToNorthwestScreenshot.center = [self movePoint:northwestFrameCenter
                                                              byX:translation.x andY:translation.y];

        //[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    }
    else if (recognizer.state == UIGestureRecognizerStateEnded)
    {
        SFCYRegion* newRegion;
        UIView* viewToMoveToCenter;
        CGSize slideVector;
        NSInteger movedByX = 0;
        NSInteger movedByY = 0;

        float thresholdPercentage = 0.4;
        BOOL isOverThresholdToNorth = translation.y > (mainFrame.size.height * thresholdPercentage);
        BOOL isOverThresholdToSouth = -translation.y > (mainFrame.size.height * thresholdPercentage);
        BOOL isOverThresholdToEast = -translation.x > (mainFrame.size.width * thresholdPercentage);
        BOOL isOverThresholdToWest = translation.x > (mainFrame.size.width * thresholdPercentage);

        if (isOverThresholdToNorth && self.region.regionToNorth != nil)
        {
            movedByY = -1;

            if (isOverThresholdToEast && self.region.regionToNorth.regionToEast != nil)
            {
                //Northeast
                newRegion = self.region.regionToNorth.regionToEast;
                viewToMoveToCenter = self.regionToNortheastScreenshot;
                movedByX = 1;
            }
            else if (isOverThresholdToWest && self.region.regionToNorth.regionToWest != nil)
            {
                //Northwest
                newRegion = self.region.regionToNorth.regionToWest;
                viewToMoveToCenter = self.regionToNorthwestScreenshot;
                movedByX = -1;
            }
            else
            {
                //North
                newRegion = self.region.regionToNorth;
                viewToMoveToCenter = self.regionToNorthScreenshot;
            }
        }
        else if (isOverThresholdToSouth && self.region.regionToSouth != nil)
        {
            movedByY = 1;

            if (isOverThresholdToEast && self.region.regionToSouth.regionToEast != nil)
            {
                //Southeast
                newRegion = self.region.regionToSouth.regionToEast;
                viewToMoveToCenter = self.regionToSoutheastScreenshot;
                movedByX = 1;
            }
            else if (isOverThresholdToWest && self.region.regionToSouth.regionToWest != nil)
            {
                //Southwest
                newRegion = self.region.regionToSouth.regionToWest;
                viewToMoveToCenter = self.regionToSouthwestScreenshot;
                movedByX = -1;
            }
            else
            {
                //South
                newRegion = self.region.regionToSouth;
                viewToMoveToCenter = self.regionToSouthScreenshot;
            }
        }
        else if (isOverThresholdToEast && self.region.regionToEast != nil)
        {
            //East
            newRegion = self.region.regionToEast;
            viewToMoveToCenter = self.regionToEastScreenshot;
            movedByX = 1;
        }
        else if (isOverThresholdToWest && self.region.regionToWest != nil)
        {
            //West
            newRegion = self.region.regionToWest;
            viewToMoveToCenter = self.regionToWestScreenshot;
            movedByX = -1;
        }
        else
        {
            //None, so return to start:
            newRegion = self.region;
            viewToMoveToCenter = self.regionScreenshot;
        }

        slideVector = CGSizeMake(mainFrameCenter.x - viewToMoveToCenter.center.x,
                                 mainFrameCenter.y - viewToMoveToCenter.center.y);

        [UIView animateWithDuration:0.2
                         animations:^
         {
             viewToMoveToCenter.alpha = 1;
             if (![self.regionScreenshot isEqual:viewToMoveToCenter])
             {
                 self.regionScreenshot.alpha = transparencyLevel;
             }
             self.regionScreenshot.center = [self movePoint:self.regionScreenshot.center
                                                        byX:slideVector.width andY:slideVector.height];
             self.regionToNorthScreenshot.center =  [self movePoint:self.regionToNorthScreenshot.center
                                                                byX:slideVector.width andY:slideVector.height];
             self.regionToEastScreenshot.center =  [self movePoint:self.regionToEastScreenshot.center
                                                               byX:slideVector.width andY:slideVector.height];
             self.regionToSouthScreenshot.center =  [self movePoint:self.regionToSouthScreenshot.center
                                                                byX:slideVector.width andY:slideVector.height];
             self.regionToWestScreenshot.center =  [self movePoint:self.regionToWestScreenshot.center
                                                               byX:slideVector.width andY:slideVector.height];
             self.regionToNortheastScreenshot.center = [self movePoint:self.regionToNortheastScreenshot.center
                                                                   byX:slideVector.width andY:slideVector.height];
             self.regionToSoutheastScreenshot.center = [self movePoint:self.regionToSoutheastScreenshot.center
                                                                   byX:slideVector.width andY:slideVector.height];
             self.regionToSouthwestScreenshot.center = [self movePoint:self.regionToSouthwestScreenshot.center
                                                                   byX:slideVector.width andY:slideVector.height];
             self.regionToNorthwestScreenshot.center = [self movePoint:self.regionToNorthwestScreenshot.center
                                                                   byX:slideVector.width andY:slideVector.height];
         }
                         completion:^(BOOL finished)
         {
             if (finished)
             {
                 //Remove the old views:
                 self.collectionView.alpha = 1;
                 [self.regionScreenshot removeFromSuperview];
                 [self.regionToNorthScreenshot removeFromSuperview];
                 [self.regionToEastScreenshot removeFromSuperview];
                 [self.regionToSouthScreenshot removeFromSuperview];
                 [self.regionToWestScreenshot removeFromSuperview];
                 [self.regionToNortheastScreenshot removeFromSuperview];
                 [self.regionToSoutheastScreenshot removeFromSuperview];
                 [self.regionToSouthwestScreenshot removeFromSuperview];
                 [self.regionToNorthwestScreenshot removeFromSuperview];
                 self.regionScreenshot = nil;
                 self.regionToNorthScreenshot = nil;
                 self.regionToEastScreenshot = nil;
                 self.regionToSouthScreenshot = nil;
                 self.regionToWestScreenshot = nil;
                 self.regionToNortheastScreenshot = nil;
                 self.regionToSoutheastScreenshot = nil;
                 self.regionToSouthwestScreenshot = nil;
                 self.regionToNorthwestScreenshot = nil;
             }
         }];

        if (![self.regionScreenshot isEqual:viewToMoveToCenter])
        {
            self.region = newRegion;
            [self reloadRegion];
            [self movedRegionByX:movedByX andY:movedByY];
        }

        [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    }
}

这是一个演示问题的图像。我在“郊区”单元格上执行选择,然后平移,然后我不再能够在该单元格上执行选择,但仍然可以选择其他单元格:

更新 3:所有手势

当我滑动手势和捏合手势时也会发生这种情况。如果我添加双指滑动手势,原点下的两个单元格都会受到影响。

【问题讨论】:

  • 显示代码。您创建的图像会发生什么变化?
  • 您说:“平移创建视图的图像并将其在屏幕周围平移。”平移结束后此图像会发生什么情况?也许那张图片挡住了你的触摸。
  • @Wain:我添加了一个可以回答您问题的更新。图像从超级视图中删除并设置为零。由于我使用的是 ARC,因此我认为它会在此之后被处理掉。
  • @Lebyrt:我添加了一个更新来回答你的问题。
  • @Wain:添加了代码和 gif。

标签: ios objective-c selection uicollectionviewcell pan


【解决方案1】:

确保regionScreenshot 和您添加到视图层次结构的任何其他视图都将userInteractionEnabled 设置为NO

还将您的单元格及其内容的clipsToBounds 设置为YES。有时视图看起来不错,但实际上它们“比看起来要小得多”。

【讨论】:

    【解决方案2】:

    在平移时,我在生成用于相邻区域的屏幕截图的过程中调用了[self.collectionView reloadData]。在手势处于活动状态时重新加载单元格似乎会干扰单个单元格处理手势的能力。

    作为一种解决方法,我改为向控制器添加了第二个隐藏的 UICollectionView,并将数据加载到该视图中并对其进行截图而不是主视图。在手势完成并选择新区域之前,主集合视图无需重新加载数据。

    UIView* aScreenshot = [self.secondaryCollectionView snapshotViewAfterScreenUpdates:YES];

    【讨论】:

      猜你喜欢
      • 2017-06-24
      • 2016-05-02
      • 1970-01-01
      • 2013-08-03
      • 2017-07-14
      • 2021-03-23
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      相关资源
      最近更新 更多