Pang Gesture识别器停止

时间:2015-07-09 14:18:44

标签: ios objective-c uiview uipangesturerecognizer

想要使用像UIView这样的UIScrollView更多的原因,我使用PanGestureRecognizer创建一个简单的代码:

- (IBAction)moveUp:(UIPanGestureRecognizer *)recognizer {

    CGPoint translation = [recognizer translationInView:self.containerView];
    recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];

}

但我希望在containerView底部位于准确位置时停止拖动,请按照屏幕进行操作:

这是完整的viewController,您看到的所有按钮都位于containerView

enter image description here

这是我打开应用程序的时候:

enter image description here

标题图片位于ViewController下方,您看到的所有按钮都位于containerView内,现在我想用绝对y修复此位置,我的containerView无法拖动下来。

现在功能无法停止,当我拖动时会发生这种情况:

enter image description here

我的containerView可以拖动containerView的末尾,我不希望这是可能的,我想阻止在containerView的末尾像这个屏幕一样向上拖动:

enter image description here

当我再次向下拖动时,我想停止在起始位置(屏幕1)拖动。

感谢您的任何想法。

1 个答案:

答案 0 :(得分:1)

乍一看,你试图让我听起来很有趣,所以我想尝试一下。

我将手势识别器的调用修改为以下内容:

- (IBAction)panned:(UIPanGestureRecognizer *)recognizer
{
    CGPoint translation = [recognizer translationInView:yourContainerView];

    CGFloat yWithinBounds = 0.0f;

    if(recognizer.view.center.y + (recognizer.view.bounds.size.height / 2.0f) > yourContainerView.bounds.size.height)
    {
        yWithinBounds = yourContainerView.bounds.size.height - (recognizer.view.bounds.size.height / 2.0f);
        [UIView animateWithDuration:1.0f animations:^
        {
            recognizer.view.center = CGPointMake(recognizer.view.center.x, yWithinBounds);
        }];
    }
    else if(recognizer.view.center.y - (recognizer.view.bounds.size.height / 2.0f) < yourContainerView.bounds.origin.y)
    {
        yWithinBounds = yourContainerView.bounds.origin.y + (recognizer.view.bounds.size.height / 2.0f);
        [UIView animateWithDuration:1.0f animations:^
        {
            recognizer.view.center = CGPointMake(recognizer.view.center.x, yWithinBounds);
        }];
    }
    else
    {
        recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
        [recognizer setTranslation:CGPointMake(0.0f, 0.0f) inView:self.view];
    }
}

在第一个if中,我们正在检查所包含视图的当前中心点+其大小的一半是否超出 底部的包含视图的范围 ;如果它是,而不是简单地禁止它进一步,我冒昧地把它放在一个动画块中,以使包含的视图动画回到包含视图内,以便它在视觉上看起来更好一些。

else-if中,除了这次包含视图的顶部之外我们正在做同样的事情 - 我们正在检查包含的视图是否超出了 top ;如果是,我们会在包含视图中将其设置为动画。

如果达到了else子句,那就意味着包含的视图在包含视图的范围内 - 在这里,我们只是像你原来那样翻译它。

以下是我将视图设置为test的方法:

yourContainerView = [[UIView alloc] initWithFrame:self.view.bounds];
yourContainerView.backgroundColor = [UIColor brownColor];
[self.view addSubview:yourContainerView];

UIView *viewWithinContainer = [[UIView alloc] initWithFrame:(CGRect){{yourContainerView.bounds.origin.x, yourContainerView.bounds.origin.y}, yourContainerView.bounds.size.width, 50.0f}]; 
viewWithinContainer.backgroundColor = [UIColor yellowColor];
[yourContainerView addSubview:viewWithinContainer];

UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panned:)];
[viewWithinContainer addGestureRecognizer:panGesture];

随意调整容器内视图的height(即50.0f到其他值)(此处:viewWithinContainer);设置代码的方式,即使您更改height,也不需要更改其他任何值。

您还可以根据需要更改动画持续时间。

我现在正在我的模拟器中上下移动物体;看起来很简单但很有趣。

问题更新后更新:

您的新更新似乎与您最初的要求有些不同,但这是解决方案:

复杂性是方向。还有其他方法可以找到;但是我在这里使用我的,我们不需要创建另一个变量。

如果您使用的是故事板,请为容器视图设置IBOutlet,因为我们希望获得以下值(在initWithFrameinitWithCoder中执行以下操作) :

p1 = viewWithinContainer.center.y;
p2 = viewWithinContainer.center.y - (yourContainerView.bounds.size.height - viewWithinContainer.bounds.size.height);

请将p1p2设置为ivars:

CGFloat p1;
CGFloat p2;

以下是包含视图 更大 的更新方法,而不是包含视图:

- (IBAction)panned:(UIPanGestureRecognizer *)recognizer
{
    CGPoint translation = [recognizer translationInView:yourContainerView];

    if(translation.y < 0)
    {
        if(recognizer.view.center.y + (recognizer.view.bounds.size.height / 2.0f) + translation.y > yourContainerView.bounds.size.height)         {
            recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
            [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
        }
        else
        {
            recognizer.view.center = CGPointMake(recognizer.view.center.x, p2);
            [recognizer setTranslation:translation inView:self.view];
        }
    }
    else if(translation.y > 0)
    {
        if(recognizer.view.center.y - (recognizer.view.bounds.size.height / 2.0f) + translation.y < yourContainerView.bounds.origin.y)
        {
            recognizer.view.center = CGPointMake(recognizer.view.center.x, recognizer.view.center.y + translation.y);
            [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
        }
        else
        {
            recognizer.view.center = CGPointMake(recognizer.view.center.x, p1);
            [recognizer setTranslation:translation inView:self.view];
        }
    }
}

该方法将确保在向下滚动时,所包含视图的顶部将停在 顶部 上容器的边缘;当您向上滚动时,在 底部 的容器边缘。

我在模拟器中运行了这个;和japp一样,这很有趣。请享用。 :-)