试图使 UITableViewCell 可滑动和可点击,同时保持 UITableView 可滚动,为啥我的单元格滑动有时只能工作?
Posted
技术标签:
【中文标题】试图使 UITableViewCell 可滑动和可点击,同时保持 UITableView 可滚动,为啥我的单元格滑动有时只能工作?【英文标题】:Trying to make UITableViewCell slideable AND tappable, while also keeping the UITableView scrollable, why is my cell sliding only working sometimes?试图使 UITableViewCell 可滑动和可点击,同时保持 UITableView 可滚动,为什么我的单元格滑动有时只能工作? 【发布时间】:2013-04-28 19:32:44 【问题描述】:我有一个 UITableView,它的单元格是 UITableViewCell 的子类,具有顶部 UIView 和底部 UIView,如果用户拖动手指,顶部 UIView 可以左右移动。
我通过向每个 UITableViewCell 添加一个平移手势识别器来使其工作。很简单的东西。但我只想要水平平移,但是当它打算向上滚动时,它会检测到整个单元格的垂直平移,这会导致 UITableView 不移动。
我试图做到这一点,只有当用户将他/她的手指水平平移超过 5 像素时才会检测到手势,但它似乎不起作用。滚动效果很好,我可以点击单元格,但我在一个单元格上滑动十次,它可能会工作一次。
我不知道为什么。
相关代码:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)recognizer
if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]])
NSLog(@"hi");
CGPoint translation = [(UIPanGestureRecognizer *)recognizer translationInView:self];
if (translation.x > 5 || translation.x < -5)
return YES;
else
return NO;
else
return YES;
- (void)pannedCell:(UIPanGestureRecognizer *)recognizer
if (recognizer.state == UIGestureRecognizerStateBegan)
_firstTouchPoint = [recognizer translationInView:self];
else if (recognizer.state == UIGestureRecognizerStateChanged)
CGPoint touchPoint = [recognizer translationInView:self];
// Holds the value of how far away from the first touch the finger has moved
CGFloat xPos;
// If the first touch point is left of the current point, it means the user is moving their finger right and the cell must move right
if (_firstTouchPoint.x < touchPoint.x)
xPos = touchPoint.x - _firstTouchPoint.x;
if (xPos <= 0)
xPos = 0;
else
xPos = -(_firstTouchPoint.x - touchPoint.x);
if (xPos >= 0)
xPos = 0;
if (xPos > 10 || xPos < -10)
// Change our cellFront's origin to the xPos we defined
CGRect frame = self.cellFront.frame;
frame.origin = CGPointMake(xPos, 0);
self.cellFront.frame = frame;
else if (recognizer.state == UIGestureRecognizerStateEnded)
[self springBack];
else if (recognizer.state == UIGestureRecognizerStateCancelled)
[self springBack];
我究竟应该怎么做才能使这个实现更好地工作?
【问题讨论】:
【参考方案1】:一个很好的方法是确定手势识别器在哪个方向上翻译最多并使用它,而不是在移动某个值时才开始平移。它大大减少了您需要的代码量,并且在我的测试中运行良好。
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
CGPoint translation = [(UIPanGestureRecognizer*)gestureRecognizer translationInView:self.superview];
return fabsf(translation.x) > fabsf(translation.y)
return YES;
现在您的视图滑动变得更简单了。此代码允许您向任一方向拖动。
- (void)drag:(UIPanGestureRecognizer *)sender
CGPoint translation = [sender translationInView:self.superview];
CGRect frame = self.upperView.frame;
switch (sender.state)
case UIGestureRecognizerStateChanged:
frame.origin.x = translation.x;
[self.upperView setFrame:frame];
break;
case UIGestureRecognizerStateBegan:
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateFailed:
default:
break;
此外,您可能希望让您的手势识别器与其他人一起工作(如处理表格视图滚动的识别器),但gestureRecognizerShouldBegin:
中的代码似乎可以毫无问题地处理这个问题。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
return YES;
另外请注意,我使用的是self.superview
,而不是像您一样使用self
。这是因为文档的translationInView:
部分中的这一行:
应在其坐标系中计算平移手势平移的视图。如果您想调整视图的位置以使其保持在用户的手指下,请求在该视图的超级视图坐标系中进行平移。
【讨论】:
以上是关于试图使 UITableViewCell 可滑动和可点击,同时保持 UITableView 可滚动,为啥我的单元格滑动有时只能工作?的主要内容,如果未能解决你的问题,请参考以下文章