使用 UIPanGestureRecognizer 时设置可拖动 UIView 的位置限制
这个问题与我最近发表的这篇文章有一些关系: 拖动一个 UIView 一半,然后它自己移动
简而言之,我有一个可拖动的 UI 视图在窗口底部部分可见。有一个“拉动选项卡”,用户可以使用它在屏幕上向上或向下拖动视图。我使用此代码对上下位置的 Y 位置进行了限制,但我不知道这是否是正确的方法:
- (void)panPiece:(UIPanGestureRecognizer *)gestureRecognizer
{
UIView *piece = [gestureRecognizer view];
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)
{
CGPoint velocity = [gestureRecognizer velocityInView:[piece superview]];
CGPoint translation = [gestureRecognizer translationInView:[piece superview]];
if(velocity.y < 0) //user is dragging the view upwards the screen
{
// Set the maximum Ypos as the top 1/3rd of the screen
CGFloat maxYPos = self.view.frame.size.height/3;
if(blogTextView.frame.origin.y >= maxYPos)
{
[piece setCenter:CGPointMake([piece center].x, [piece center].y + translation.y)];
[gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
}
}
else
{
// User is dragging the view downwards the screen
// Set the lowest Y position to be 420
if(blogTextView.frame.origin.y <= 420) //size of remaining view
{
[piece setCenter:CGPointMake([piece center].x, [piece center].y + translation.y)];
[gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
}
}
}
}
我认为这看起来很难看,但如果用户拖动视图,它会起作用慢慢地。问题是,如果用户在屏幕上非常快速地向上或向下拖动视图,则视图可能会被拉到超出我对 Y 位置设置的限制。例如,在底部可拖动视图的默认状态下,我能够以快速的速度将视图一直拖动到导航栏上方!
是否有正确的方法来设置视图可以拖动多远的限制,并在此gestureRecognizer回调中正确处理?
作为参考,以下是测试应用程序的图片:
谢谢!
This question has some relation to this post I made recently: Drag a UIView part-way, then it moves on its own
In short, I have a draggable UI view partly visible at the bottom of the window. There is a "pull tab" that the user can use to drag the view upwards or downwards on the screen. I have placed limits on the Y position for the upper and lower positions using this code, but I have no clue if this is the right way to do it:
- (void)panPiece:(UIPanGestureRecognizer *)gestureRecognizer
{
UIView *piece = [gestureRecognizer view];
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)
{
CGPoint velocity = [gestureRecognizer velocityInView:[piece superview]];
CGPoint translation = [gestureRecognizer translationInView:[piece superview]];
if(velocity.y < 0) //user is dragging the view upwards the screen
{
// Set the maximum Ypos as the top 1/3rd of the screen
CGFloat maxYPos = self.view.frame.size.height/3;
if(blogTextView.frame.origin.y >= maxYPos)
{
[piece setCenter:CGPointMake([piece center].x, [piece center].y + translation.y)];
[gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
}
}
else
{
// User is dragging the view downwards the screen
// Set the lowest Y position to be 420
if(blogTextView.frame.origin.y <= 420) //size of remaining view
{
[piece setCenter:CGPointMake([piece center].x, [piece center].y + translation.y)];
[gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
}
}
}
}
I think this looks ugly, but it works if the user is dragging the view slowly. The problem is if the user drags the view very rapidly upward or downward the screen, then the view can be pulled beyond the limits I put on the Y position. For example, in the default state with the draggable view on the bottom, I was able to drag the view in a snap-like speed all the way to over the navigation bar!
Is there a correct way to set the limits of how far a view can be dragged and will be dealt with correctly in this gestureRecognizer callback?
For reference, here are pics of the test app:
Default screen with draggable view at the bottom and the pull tab
View dragged up to its correct max Y position
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于,在以下代码中:
而这一个:
您应该使用
blogTextView.frame.origin.y
的未来值(如果执行 if 内的代码,您将获得的值)集团。)换句话说,你总是在做额外的翻译。当缓慢拖动时你不会注意到这一点,因为额外的平移并不重要,但当快速拖动时它就变得很重要,你会注意到错误的结果。
The problem is that in the following code:
And this one:
You you should use the future value of
blogTextView.frame.origin.y
(the value that you would obtain if you executed the code inside the if bloc.)In other words, you are always doing an extra translation. And you can't notice that when dragging slowly because the extra translation is not important, but it becomes important when dragging quickly and you can notice the wrong result.