手势识别器停止

Pang Gesture Recognizer stop

想像 UIScrollView 一样使用 UIView 出于更多原因,我使用 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

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

header 图像在下面的 ViewController 中,您看到的所有按钮都在 containerView 中,现在我想用绝对 y 修复这个位置,我的 containerView拖不下来

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

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

当我再次向下拖动时,我想在起始位置(屏幕 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 中,我们正在检查您包含的视图的当前中心点 + 它的一半大小是否超出 [= 上的包含视图的边界61=]底部;如果是,而不是简单地禁止它走得更远,我冒昧地把它放在一个动画块中,使包含的视图动画回到包含视图内,这样它在视觉上看起来更好一些。

else-if 中,我们正在做同样的事情,除了这次是针对包含视图的顶部 - 我们正在检查包含的视图是否在 [=61 上越界=]顶部;如果是,我们将其动画化回包含的视图中。

如果达到 else 子句,则意味着包含的视图在包含视图的范围内 - 在这里,我们只是像您最初做的那样 t运行slate 它。

以下是我如何将视图设置为测试:

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];

随意调整容器内视图(特此:viewWithinContainer)的height(即50.0f为其他值);代码的设置方式,即使您更改了 height.

,您也不需要更改任何其他值

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

我现在正在我的模拟器中上下移动这个东西;看起来简单但玩起来很有趣。


问题更新后更新:

您的新更新似乎与您最初提出的要求有很大不同,但解决方案如下:

复杂就是方向。还有其他方法可以找出答案;但我在这里使用我的,我们不需要通过它创建另一个变量。

如果你使用的是storyboard,请为你的container view设置一个IBOutlet,因为我们要获取以下值(在initWithFrame和[=24=中执行以下操作) ]):

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];
        }
    }
}

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

上的容器边缘

我在模拟器中运行这个;和 japp,这样做很有趣。享受。 :-)