我有一个UITableView,其中的单元格是UITableViewCell的子类,这些子类具有顶部UIView和底部UIView,如果用户拖动手指,则顶部UIView可以左右移动。
我通过向每个UITableViewCell添加一个平移手势识别器来使其工作。很简单的东西。但是我只想要水平平移,但是当它打算向上滚动时,它将检测到整个单元格的垂直平移,这将导致UITableView不移动。
我试图做到这一点,以便仅在用户将手指水平平移超过5px时才能检测到手势,但似乎不起作用。滚动条工作正常,我可以轻按单元格,但是在单元格上滑动了十次,可能只有一次。
我不知道为什么。
相关代码:
- (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];
}
}
我到底应该怎么做才能使此实现更好地工作?
最佳答案
做到这一点的一种不错的方法,而不必弄乱只有在移动了某个值后才开始平移,这是确定手势识别器向哪个方向平移最多并使用该方向。它减少了您所需的代码量,并且在我的测试中效果很好。
- (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:
部分中的这一行:应该在其坐标系中计算平移手势的平移的视图。如果要调整视图的位置以将其保持在用户的手指下,要求在该视图的 super 视图的坐标系中进行平移。