Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 为什么我的平移手势只会轻推它的视图并停止?_Ios_Uipangesturerecognizer - Fatal编程技术网

Ios 为什么我的平移手势只会轻推它的视图并停止?

Ios 为什么我的平移手势只会轻推它的视图并停止?,ios,uipangesturerecognizer,Ios,Uipangesturerecognizer,以下是UIPanGesture子类: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"touches began"); self ->origLoc = [[touches anyObject] locationInView:self.view.superview]; [super touchesBegan:touches withEvent:event]; } -

以下是UIPanGesture子类:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"touches began");
   self ->origLoc = [[touches anyObject] locationInView:self.view.superview];
   [super touchesBegan:touches withEvent:event];
}


- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.state == UIGestureRecognizerStatePossible) {
    CGPoint loc = [[touches anyObject] locationInView:self.view.superview];
    CGFloat deltaX = fabsf(loc.x - origLoc.x);
    CGFloat deltaY = fabsf(loc.y - origLoc.y);
    if (deltaY >= deltaX) {
        self.state = UIGestureRecognizerStateFailed;
    } else {
    [super touchesMoved:touches withEvent:event];
    }
}
}

- (CGPoint) translationInView:(UIView *)v {

CGPoint proposedTranslation = [super translationInView:v];
proposedTranslation.y = 0;
return proposedTranslation;

}
下面是我的子类UIPanGesture调用的方法:

- (void)dragging: (UIPanGestureRecognizer *)p {    

UIView *vv = p.view;

if (p.state == UIGestureRecognizerStateBegan || p.state == UIGestureRecognizerStateChanged) {
    CGPoint delta = [p translationInView:vv.superview];
    CGPoint c = vv.center;
    c.x += delta.x;
    c.y += delta.y;
    vv.center = c;
    [p setTranslation:CGPointZero inView:vv.superview];
 }    
}
当我尝试拖动视图时,它只移动了很小的一部分,然后停止。我需要不断地推它,让它移动。有什么想法吗

提前感谢,


Michael。

触摸移动中的故障情况看起来对早期移动非常敏感

考虑让它不那么敏感

- (BOOL)movementIsHorizontalX:(CGFloat)x andY:(CGFloat) y {

    CGFloat absX = fabs(x);
    CGFloat absY = fabs(y);

    // if x is small, then accept small y values but not large ones
    if (absX < 4) return absY < 4;

    // now we can express horizontal-ness as a slope.  we've ruled out small x, so this is a stable calculation
    CGFloat slope = absY / absX;
    return slope < 0.10;

    // you could generalize by passing in the x threshold and percentage slope constants
}
-(BOOL)movementIsHorizontalX:(CGFloat)x安迪:(CGFloat)y{
cGx=fabs(x);
CGFloat absY=晶圆厂(y);
//如果x很小,则接受较小的y值,但不接受较大的y值
如果(absX<4)返回absY<4;
//现在我们可以用斜率来表示水平度,我们已经排除了小x,所以这是一个稳定的计算
CGFloat斜率=absY/absX;
回归斜率<0.10;
//您可以通过传递x阈值和百分比斜率常数来进行概括
}

我意识到了我的错误。我搬家了

    [super touchesMoved: touches withEvent:event];  
在if语句之外,现在它似乎工作正常。现在还不是100%确定它为什么能工作,但我很高兴它能工作


现在,为了弄清楚如何防止UIScrollView接受平移手势,直到该手势取消/失败…

在我之前的评论中,我不清楚为什么要进行子类化,但您澄清了这一点,因为您有多个手势处理程序。很好

下面是一些自定义平移手势的示例代码HorizontalPangestureRecognitor,只有在第一个移动是水平的情况下才会触发:

// HorizontalPanGestureRecognizer.h

#import <UIKit/UIKit.h>

@interface HorizontalPanGestureRecognizer : UIPanGestureRecognizer
@end
然后处理程序看起来像:

- (void)handleCustomPan:(UIPanGestureRecognizer *)sender 
{    
    switch (sender.state) {
        case UIGestureRecognizerStateChanged:
            if (!_panLabel)
            {
                // In my case I'm creating a UILabel to drag around, whereas you might just drag
                // whatever countrol you want to drag.
                //
                // But, regardless, I'm keeping track of the original center in _panLabelOrigCenter

                [self makePanLabel:sender]; 
            }

            CGPoint translate = [sender translationInView:self.view];
            _panLabel.center = CGPointMake(_panLabelOrigCenter.x + translate.x, _panLabelOrigCenter.y + translate.y);

            break;

        case UIGestureRecognizerStateEnded:
            [self removePanLabel];
            break;

        default:
            break;
    }
}

(显然,这是ARC代码。如果不是ARC,则添加必要的额外代码行以进行例行内存管理。)

danh可能是正确的想法。出于好奇,你想用这个子类的泛手势识别器做什么?如果你只是想左右平移,有更简单的方法来解决这个问题。或者您是否有其他平移手势识别器处理垂直运动,并且您正在尝试检测要使用的手势识别器?但我认为,一旦你锁定了一个特定的识别器,你就会停止进一步检查滑动方向(以允许手指微小的移动产生微小的变化)。它作用于GMGridView(UIScrollview)中的一个单元格如果检测到水平平移,我只希望能够向左或向右平移其中一个单元格中的内容,如果检测到垂直平移,则可以滚动整个视图。你提到我应该停止检查滑动方向,我该怎么做?底线是,有一个变量跟踪你是否确认了你是否检查了初始运动的方向,还有一个变量告诉你它是否是水平的。然后,您可以检查跟踪初始移动是否为水平的变量,以确定是否将状态更改为UIgestureRecognitizerStateFailed。看我的答案。是的,这是有道理的。有更好的地方放支票吗?我希望视图只接受水平移动,并防止superview(UIScrollView)的垂直滚动。除非滚动最初是垂直的,否则superview可以滚动,水平移动可以忽略。我认为这是一个检查的好地方,但我们可以改进测试。请参阅我的编辑。感谢您的回复。我现在有以下内容,请看下面:我仍然只是在对代码进行这些更改。我在拖动中添加了一个NSLog,它确实在重复调用该方法,但视图在经过非常短暂的轻推后停止移动。如果水平启动,我在回答中包含的代码将处理平移(因此UITableView的手势识别器无法获得它),但忽略它,并将其传递到tableview的标准手势,如果垂直启动,则可识别该手势。如果我误解了你的意图,请告诉我。嗨,罗布,我只是想用上面的方法,但有两个错误1。“UIPanGestureRecognizer”没有可见的@interface声明选择器“touchesEnded:withEvent:”2。分配给readonly属性可以帮助您。@PavanMore您必须
#import
(这是一个标题,用于对手势识别器进行子类化,公开一些其他私有方法,以及将一些典型的
readonly
属性设置为
readwrite
)。很抱歉,这不清楚,我试图澄清我的答案。
HorizontalPanGestureRecognizer *recognizer = [[HorizontalPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleCustomPan:)];
[self.view addGestureRecognizer:recognizer];
- (void)handleCustomPan:(UIPanGestureRecognizer *)sender 
{    
    switch (sender.state) {
        case UIGestureRecognizerStateChanged:
            if (!_panLabel)
            {
                // In my case I'm creating a UILabel to drag around, whereas you might just drag
                // whatever countrol you want to drag.
                //
                // But, regardless, I'm keeping track of the original center in _panLabelOrigCenter

                [self makePanLabel:sender]; 
            }

            CGPoint translate = [sender translationInView:self.view];
            _panLabel.center = CGPointMake(_panLabelOrigCenter.x + translate.x, _panLabelOrigCenter.y + translate.y);

            break;

        case UIGestureRecognizerStateEnded:
            [self removePanLabel];
            break;

        default:
            break;
    }
}