【发布时间】: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