手势识别器停止
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);
请将p1
和p2
设置为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,这样做很有趣。享受。 :-)
想像 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);
请将p1
和p2
设置为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,这样做很有趣。享受。 :-)