在GMSMapView上拖动时,iOS布局动画会忽略持续时间 [英] iOS layout animation ignores duration when fired on GMSMapView dragging

查看:99
本文介绍了在GMSMapView上拖动时,iOS布局动画会忽略持续时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以在下面比较两个gif文件时看到问题。 收缩和拉伸动画均基于约束操作,并且 [self layoutIfNedeed] 放置在 -animateWithDuration 内块。如您所见,当地图不移动时,它可以按预期工作。但是,收缩动画会在您开始拖动地图时立即发生。如果仔细观察,您可能会注意到cornerRadius动画仍然有效。这告诉我,它可能与地图有关(内部为scrollView?不知道Google地图的工作原理),称其为自己的布局块会干扰我的动画。或者可能是由于cornerRadius动画是使用CABasicAnimation而不是UIView动画完成的。

You can see the problem comparing two gifs below. Both "shrink" and "stretch" animation are based on constraints manipulation and [self layoutIfNedeed] is placed inside -animateWithDuration block. As you can see it works as intended when the map is not moving. But "shrink" animation happens instantly as you start dragging the map. If you look closely you might notice that cornerRadius animation still works. This tells me that it might have something to do with map (scrollView inside? no idea how google map works) calling it's own layout blocks that interfere with my animation. Or it might be due to the fact that cornerRadius animation is done using CABasicAnimation, not UIView animation.

动画InfoView不是mapView的子视图。当mapView调用内部布局方法时,不确定是否会影响infoView的布局。

Animated InfoView is not a subview of the mapView. Not sure if it should affect my infoView's layout when mapView is calling inner layout methods.

我尝试了所有组合选项 UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionOverrideInheritedOptions 只是看看是否有帮助。

I've tried all the options combined UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionOverrideInheritedOptions just to see if it helps. It does not.

我认为我可以直接克服此操纵框架而不是操纵约束,并且对用户而言,它看起来是相同的,但是我觉得使用约束是如此更优雅。我尝试避免尽可能多地操纵帧并使用自动布局。

I think I can overcome this manipulating frame directly instead of manipulating constraints and it will look the same to the user, but I feel like using constraints is so much more elegant. I try to avoid manipulating frames as much as possible and use autolayout.

有什么想法会导致这种情况,以及如何使用自动布局动画来克服此问题?

Any ideas what's causing this and how to overcome this problem using autolayout animation?

更新

我已经尝试过直接对帧进行动画处理-结果是相同的。因此,它与自动布局无关。看来当前的视图动画由于某种原因已停止。

I've tried animating frame directly - result is the same. So it has nothing to do with autolayout. It seems like current view animation is stopped for some reason.

如果我用CABasicAnimation替换UIView动画块,则它的工作原理就像一种魅力。

If I replace my UIView animation block with CABasicAnimation it works like a charm.

我被要求发布一些动画代码:

I was asked to post some animation code:

- (void)shrink {

    if (!self.isStretched) return;

    self.stretched = NO;

    [self hideImageAndLabels];

    [self.indicatorView startAnimating];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
    animation.duration = duration;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.fromValue = @0;
    animation.toValue = @(shrinkedSize / 2.0);

    [self.layer addAnimation:animation forKey:@"cornerRadiusAnimationRounded"];
    self.layer.cornerRadius = shrinkedSize / 2.0;

    self.heightConstraint.constant = shrinkedSize;
    self.widthConstraint.constant = shrinkedSize;
    self.positionYConstraint.constant = 0;
    self.triangleHeightConstraint.constant = 0;
    self.trianglePositionYConstraint.constant = 14;

    [UIView animateWithDuration:duration * 2 delay:0 usingSpringWithDamping:0.85 initialSpringVelocity:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
        [self layoutIfNeeded];
    } completion:^(BOOL finished) {
            //
    }];


}


推荐答案

我在Google( https://code.google.com/p/gmaps-api-issues/issues/detail? id = 10349 ),这是他们的回应:

I opened a bug on this issue with Google (https://code.google.com/p/gmaps-api-issues/issues/detail?id=10349), and this was their response:


我们的理解是,发生这种情况是因为mapView:willMove:已在CoreAnimation事务中进行调用。我们建议的解决方法是将UIView.animateWithDuration调用包装在dispatch_async中,回到主线程。类似于以下内容:

Our understanding is that this is happening because the mapView:willMove: call is being made while already inside a CoreAnimation transaction. Our suggested work around is to wrap the UIView.animateWithDuration call within a dispatch_async back to the main thread. Something along the lines of:

dispatch_async(dispatch_get_main_queue(),^ {
//此处的动画块。
});

dispatch_async(dispatch_get_main_queue(), ^{ // animation block here. });

有帮助吗?

将UIView.animateWithDuration块放置在dispatch_async块中对于我。

Placing the UIView.animateWithDuration block inside a dispatch_async block worked for me.

这篇关于在GMSMapView上拖动时,iOS布局动画会忽略持续时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆