Ios UITableView的水平移动?
我试图区分水平滑动/平移和 在Ios UITableView的水平移动?,ios,uitableview,Ios,Uitableview,我试图区分水平滑动/平移和 在UITableView中垂直滚动。我期待的行为 模仿(从某种意义上说)是推特iPad应用程序的模仿,它已经成功了 可在屏幕上水平移动的多个UITableView。如果 我在其中一个UITableView视图上向左或向右滑动手指 它自身水平移动。如果我垂直滑动,视图将滚动为 预料之中 我很难想出正确的方法来实现这一点 行为。我看过一些关于这方面的教程,其中包括添加触摸 UITableViewCells中的事件处理程序,并重写 UITableView根据哪个方向适当地路
UITableView
中垂直滚动。我期待的行为
模仿(从某种意义上说)是推特iPad应用程序的模仿,它已经成功了
可在屏幕上水平移动的多个UITableView
。如果
我在其中一个UITableView
视图上向左或向右滑动手指
它自身水平移动。如果我垂直滑动,视图将滚动为
预料之中
我很难想出正确的方法来实现这一点
行为。我看过一些关于这方面的教程,其中包括添加触摸
UITableViewCells
中的事件处理程序,并重写
UITableView
根据哪个方向适当地路由事件
这个手势在动。我已经实现了其中一些技术,但是
没有一个工作得特别好
有人知道实施这种行为的正确方法吗?
根据
用户手指移动的方向
谢谢。我自己从来没有这样做过,但是由于UITableView是UIScrollView的一个子类,UITableView的委托也是UIScrollView委托。因此,在UITableViewController子类中,您应该能够使用UIScrollView委托并截取滚动条-确保还调用super方法。如果您希望UITableView“并排”放置,并且当您水平滑动时,您希望它们同时水平移动,(就像带有UITableView而不是图像的照片库)您可以执行以下操作: 使用UIScrollView并将UITableView添加为UIScrollView的子视图。您应该如下设置scrollview的contentSize:
CGRect bounds = scrollView.bounds;
scrollView.contentSize=CGSizeMake(bounds.size.width * kNumOfTableViews, bounds.size.height);
以便UIScrollview水平滚动,而不是垂直滚动
您可能还想使用
scrollView.pagingEnabled=YES;
取决于理想的行为
如果您垂直滑动手指,UITableView将以正常方式响应,您可以通过水平滑动手指在UITableView之间切换
有关如何有效执行此操作的更多详细信息,请参阅WWDC 2010视频会话104-使用滚动视图设计应用程序,并从此处查看源代码:。此会话介绍如何在图像之间滑动。您将使用UITableView而不是图像
但是,如果您希望每个UITableView都能够独立水平移动,并且可能与另一个UITableView重叠,就像在iPad的twitter应用程序中一样,这个解决方案对您不起作用,至少不是现成的解决方案。我已经为类似的问题挣扎了好几天,我已经研究了几种可能的解决方案。我发现了best方式也是最简单的解决方案,将UIgestureRecognitor子类化以处理水平移动并将其附加到UITableView 它的工作方式是在任何触摸事件进入UITableView(也叫UIScrollView)之前拦截它们。UITableView是UIScrollView的子类,它内置了一个自定义的UIPangestureRecognitor,用于检测拖动并相应地滚动其视图。通过添加您自己的UIgestureRecognitor子类,您可以在UIScrollView的手势识别器之前获得触感。如果您的识别器看到用户在水平拖动,它将应将其在重写的TouchsMoved:方法中的状态更改为UIgestureRecognitizerStateStarted。否则,它会将其状态设置为UIgestureRecognitizerCancelled,从而使基础UIScrollView处理触摸 以下是我的UIgestureRecognitizer子类的外观:
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface TableViewCellPanGestureRecognizer : UIGestureRecognizer
{
CGPoint startTouchPoint;
CGPoint currentTouchPoint;
BOOL isPanningHorizontally;
}
- (void)reset;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end
@implementation TableViewCellPanGestureRecognizer
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
startTouchPoint = [[touches anyObject] locationInView:nil];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
currentTouchPoint = [[touches anyObject] locationInView:nil];
if ( !isPanningHorizontally ) {
float touchSlope = fabsf((currentTouchPoint.y - startTouchPoint.y) / (currentTouchPoint.x - startTouchPoint.x));
if ( touchSlope < 1 ) {
self.state = UIGestureRecognizerStateBegan;
isPanningHorizontally = YES;
[self.view touchesCancelled:touches withEvent:event];
} else {
self.state = UIGestureRecognizerStateCancelled;
[self.view touchesCancelled:touches withEvent:event];
}
} else {
self.state = UIGestureRecognizerStateChanged;
}
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
self.state = UIGestureRecognizerStateCancelled;
[self.view touchesCancelled:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
self.state = UIGestureRecognizerStateCancelled;
}
-(void)reset
{
[super reset];
startTouchPoint = CGPointZero;
currentTouchPoint = CGPointZero;
isPanningHorizontally = NO;
}
@end
horizontalPanGesture = [[TableViewCellPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleHorizontalDrag:)];
[self addGestureRecognizer:horizontalPanGesture];
[horizontalPanGesture release];
-(void)handleHorizontalDrag:(UIGestureRecognizer *)gesture
{
UIGestureRecognizerState state = gesture.state;
// Set the touched cell
if (!touchedCell){
NSIndexPath *indexPathAtHitPoint = [self indexPathForRowAtPoint:[gesture locationInView:self]];
id cell = [self cellForRowAtIndexPath:indexPathAtHitPoint];
touchedCell = cell;
startTouchPoint = [gesture locationInView:touchedCell];
}
if ( state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged ) {
// move your views horizontally
} else if ( state == UIGestureRecognizerStateEnded || state == UIGestureRecognizerStateCancelled ) {
touchedCell = nil;
}
}
和操作方法:
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface TableViewCellPanGestureRecognizer : UIGestureRecognizer
{
CGPoint startTouchPoint;
CGPoint currentTouchPoint;
BOOL isPanningHorizontally;
}
- (void)reset;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end
@implementation TableViewCellPanGestureRecognizer
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
startTouchPoint = [[touches anyObject] locationInView:nil];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
currentTouchPoint = [[touches anyObject] locationInView:nil];
if ( !isPanningHorizontally ) {
float touchSlope = fabsf((currentTouchPoint.y - startTouchPoint.y) / (currentTouchPoint.x - startTouchPoint.x));
if ( touchSlope < 1 ) {
self.state = UIGestureRecognizerStateBegan;
isPanningHorizontally = YES;
[self.view touchesCancelled:touches withEvent:event];
} else {
self.state = UIGestureRecognizerStateCancelled;
[self.view touchesCancelled:touches withEvent:event];
}
} else {
self.state = UIGestureRecognizerStateChanged;
}
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
self.state = UIGestureRecognizerStateCancelled;
[self.view touchesCancelled:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
self.state = UIGestureRecognizerStateCancelled;
}
-(void)reset
{
[super reset];
startTouchPoint = CGPointZero;
currentTouchPoint = CGPointZero;
isPanningHorizontally = NO;
}
@end
horizontalPanGesture = [[TableViewCellPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleHorizontalDrag:)];
[self addGestureRecognizer:horizontalPanGesture];
[horizontalPanGesture release];
-(void)handleHorizontalDrag:(UIGestureRecognizer *)gesture
{
UIGestureRecognizerState state = gesture.state;
// Set the touched cell
if (!touchedCell){
NSIndexPath *indexPathAtHitPoint = [self indexPathForRowAtPoint:[gesture locationInView:self]];
id cell = [self cellForRowAtIndexPath:indexPathAtHitPoint];
touchedCell = cell;
startTouchPoint = [gesture locationInView:touchedCell];
}
if ( state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged ) {
// move your views horizontally
} else if ( state == UIGestureRecognizerStateEnded || state == UIGestureRecognizerStateCancelled ) {
touchedCell = nil;
}
}
上面的内容获取表格视图中正在触摸的当前单元格,然后在用户向左或向右拖动时对其应用水平移动。但是,如果我的手势识别器确定触摸是要垂直滚动的,它只会自动取消,并将以下触摸发送到UITableView以启动垂直滚动我会自动地打电话给你
此设置似乎比覆盖hitTest和在UITableView本身内进行各种触摸事件欺骗要简单得多。它只是立即确定触摸移动的方向。您将需要阅读-特别是关于它应如何子类化的内容。您需要确保在某些touc上前进h事件,如touchesCancelled到UITableView,因为UITableView的内置PangestureRecognitor不会像通常那样处理这些事件。显然,您希望移动整个表视图而不是单个单元格,但它应该非常简单
这个解决方案虽然简单,但我花了一段时间才完全满足我的具体需求。我对IOS开发还很陌生,所以我不得不花大量时间阅读并修补手势识别器和滚动视图来解决这个问题。让滚动视图告诉我它什么时候要移动或在移动之后移动对我没有帮助在这种情况下。在做出滚动决定之前,我需要信息。嗯……您可以使用UIPangestureRecognitor。将方向设置为左/右,并根据手势状态的变化移动表格视图。UIPangestureRecognitor不允许您限制方向,好吧。UISweep GestureRecognitor呢?UISweep手势识别器检测到刷卡。我需要不断更新位置。这是一个很好的答案,值得注意的是,此版本只支持一个方向,因为您忽略了视图的方向,将您的fromView:nil切换到fromView:self。视图将考虑旋转。您可以添加有关此方法的一些信息吗?看起来您的
handleHorizontalDrag:
方法位于UITableView子类中,但它引用了TableViewCellPangestureRecognitor中的一个属性,以及另一个属性(tou)