gpt4 book ai didi

ios - 交互式过渡,如谷歌地图 (iOS)

转载 作者:可可西里 更新时间:2023-11-01 05:44:08 25 4
gpt4 key购买 nike

我想实现与 Google map (iOS) 非常接近的东西,但我有一些疑问。

但首先,更好的解释和需要考虑的事项:

------------ 答案------------

感谢 Jugale 的贡献,这里有一个存储库,每个人都可以下载并测试所有内容。

https://github.com/vCrespoP/VCSlidingView

------------ 原始问题------------

  • 您点击 map 内的一个点,一个 View 从底部进入,但是当您与该摘要 View 交互时:
  • 请注意,只需拉动一点,导航栏就已经设置好。
  • 滚动到顶部后,您可以继续滚动,内部 ScrollView 将继续滚动。
  • 当您“反转”关闭 View 的操作时,PanGesture 不会与内部 scrollView 混淆(另一种方式相同,scrollView VS 关闭)

这是实际操作: enter image description here

疑问:

  • 我尝试将其作为交互式过渡 (UIPercentDrivenInteractiveTransition) 并在 2 个 Controller 中将 Map 与 Details 分开,但我遇到了 UIPanGesture 干扰 scrollView 的问题。
  • 也许最好将它作为一个 subview 来处理那里的所有事情?或多或少像 MBPullDownController(虽然它在 iOS8 上有一些问题)-> https://github.com/matej/MBPullDownController

那么,有人知道任何框架,已经使用过,或者知道如何以好的方式做到这一点吗?

谢谢你的时间:D

最佳答案

通过我的实现来看,以下内容似乎是正确的:

  1. 我有一个 UIViewController 的子类,它是 View Controller
  2. 我有一个 UIView 的子类,它是覆盖层(此后称为“覆盖层”)(实际上对我来说这是一个 UIScrollView 因为它需要也横向移动,但我会尝试过滤掉不必要的代码)
  3. 我有另一个加载覆盖内容的 UIView 子类(“内容包装器”)
  4. 内容包装器有一个 UIScrollView 属性,其中加载了所有其他 View (“内容 View ”)

View Controller 负责初始化叠加层,设置它的初始框架(高度是屏幕的高度)并将内容传递给它,仅此而已。

通过它的 -initWithFrame 方法,叠加层使用 UIDynamicItemBehavior 自行设置。它还创建了一些 UICollisionBehavior 对象:一个在屏幕顶部,一个在屏幕底部下方,正好位于正确的 y 位置,以便叠加层的顶部部分可见(如GIF 的第一帧)。还设置了一个 UIGravityBehavior 以保持叠加层位于较低的碰撞边界上。当然,_animator = [[UIDynamicAnimator alloc...也设置好了。

最后:

_pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan)];
_pan.delegate = self;
_pan.cancelsTouchesInView = FALSE;

overlay 类还有一些其他有用的方法,例如改变重力的方向,这样 overlay 就可以捕捉到屏幕的顶部或底部。

_pan 处理程序使用 UISnapBehavior 使叠加层在用户手指下方的屏幕上动态地上下移动:

- (void)handlePan
{
[self handlePanFromPanGestureRecogniser:_pan];
}

- (void)handlePanFromPanGestureRecogniser:(UIPanGestureRecognizer *)pan
{
CGFloat d = [pan velocityInView:self.superview.superview].y;

CGRect r = self.frame;
r.origin.y = r.origin.y + (d*0.057);

if (r.origin.y < 20)
{
r.origin.y = 20;
}
else if (r.origin.y > [UIScreen mainScreen].bounds.size.height - PEEKING_HEIGHT)
{
r.origin.y = [UIScreen mainScreen].bounds.size.height - PEEKING_HEIGHT;
}

if (pan.state == UIGestureRecognizerStateEnded)
{
[self panGestureEnded];
}
else if (pan.state == UIGestureRecognizerStateBegan)
{
[self snapToBottom];
[self removeGestureRecognizer:_tap];
}
else
{
[_animator removeBehavior:_findersnap];
_findersnap = [[UISnapBehavior alloc] initWithItem:self snapToPoint:CGPointMake(CGRectGetMidX(r), CGRectGetMidY(r))];
[_animator addBehavior:_findersnap];
}
}

- (void)panGestureEnded
{
[_animator removeBehavior:_findersnap];

CGPoint vel = [_dynamicSelf linearVelocityForItem:self];
if (fabsf(vel.y) > 250.0)
{
if (vel.y < 0)
{
[self snapToTop];
}
else
{
[self snapToBottom];
}
}
else
{
if (self.frame.origin.y > (self.superview.bounds.size.height/2))
{
[self snapToBottom];
}
else
{
[self snapToTop];
}
}

}

内容包装器监听内容 View 产生的滚动事件:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//this is our fancy way of getting the pan to work when the scrollview is in the way
if (scrollView.contentOffset.y <= 0 && _dragging)
{
_shouldForwardScrollEvents = TRUE;
}

if (_shouldForwardScrollEvents)
{
if ([_delegate respondsToSelector:@selector(theContentWrapper:isForwardingGestureRecogniserTouches:)])
{
[_delegate theContentWrapper:self isForwardingGestureRecogniserTouches:scrollView.panGestureRecognizer];
}
}
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
_dragging = FALSE;//scrollviewdidscroll must not be called after this

if (scrollView.contentOffset.y <= 0 || _shouldForwardScrollEvents)
{
if ([_delegate respondsToSelector:@selector(theContentWrapperStoppedBeingDragged:)])
{
[_delegate theContentWrapperStoppedBeingDragged:self];
}
}

_shouldForwardScrollEvents = FALSE;
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
_dragging = TRUE;
}

如您所见,当 bool shouldForwardScrollEventsTRUE 时,我们将 scrollView.panGestureRecognizer 发送到内容包装器的委托(delegate)(覆盖层) . overlay 像这样实现委托(delegate)方法:

- (void)theContentWrapper:(TheContentWrapper *)contentWrapper isForwardingGestureRecogniserTouches:(UIPanGestureRecognizer *)contentViewPan
{
[self handlePanFromPanGestureRecogniser:contentViewPan];
}

- (void)theContentWrapperStoppedBeingDragged:(TheContentWrapper *)contentWrapper
{
//because the scrollview internal pan doesn't tell use when it's state == ENDED
[self panGestureEnded];
}

希望其中至少有一部分对某人有用!

关于ios - 交互式过渡,如谷歌地图 (iOS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26604395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com