如何暂停和恢复UIView动画?

发布于 2024-09-09 02:54:31 字数 367 浏览 12 评论 0原文

我有一个带有多个 UILabel 的 UIView,它们从上到下进行动画处理,反之亦然。可以说是一种 Autoque :) 我使用 2 个函数:

-(void)goUp 
-(void)goDown 

这些函数将 UIView 动画启动到所需的位置。它们都定义了一个在最后调用另一个函数的 AnimationDidStopSelector 。这一切都很顺利。

当触摸屏幕时,使用touchesBegan,我想暂停当前动画并使用touchesMoved 事件更改UIView 的垂直位置。在 TouchesEnded 中,我想将动画恢复到所需的结束位置。

这样做的正确方法是什么?

托马斯

I have a UIView with several UILabels that is animating from top to bottom and vice versa. A sort of Autoque let's say :) I use 2 functions:

-(void)goUp 
-(void)goDown 

Those functions start a UIView animation to the required position.They both have an AnimationDidStopSelector defined that calls the other function at the end. This all works smoothly.

When touching the screen, using touchesBegan, I would like to pause the current animation and change the vertical position of the UIView using touchesMoved event. In touchesEnded I want to resume the animation to the required end position.

What would be the proper way to do so?

Thomas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

素罗衫 2024-09-16 02:54:31

我在 UIView 上创建了一个类别来暂停和停止动画:

@interface UIView (AnimationsHandler)

- (void)pauseAnimations;
- (void)resumeAnimations;

@end

@implementation UIView (AnimationsHandler)
- (void)pauseAnimations
{
    CFTimeInterval paused_time = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    self.layer.speed = 0.0;
    self.layer.timeOffset = paused_time;
}

- (void)resumeAnimations
{
    CFTimeInterval paused_time = [self.layer timeOffset];
    self.layer.speed = 1.0f;
    self.layer.timeOffset = 0.0f;
    self.layer.beginTime = 0.0f;
    CFTimeInterval time_since_pause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - paused_time;
    self.layer.beginTime = time_since_pause;
}

I've created a category on UIView to pause and stop animations:

@interface UIView (AnimationsHandler)

- (void)pauseAnimations;
- (void)resumeAnimations;

@end

@implementation UIView (AnimationsHandler)
- (void)pauseAnimations
{
    CFTimeInterval paused_time = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    self.layer.speed = 0.0;
    self.layer.timeOffset = paused_time;
}

- (void)resumeAnimations
{
    CFTimeInterval paused_time = [self.layer timeOffset];
    self.layer.speed = 1.0f;
    self.layer.timeOffset = 0.0f;
    self.layer.beginTime = 0.0f;
    CFTimeInterval time_since_pause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - paused_time;
    self.layer.beginTime = time_since_pause;
}
不知所踪 2024-09-16 02:54:31

实际上,您仍然可以根据 Vladimir 链接到的问题的答案来暂停 UIView 动画,因为它会暂停我的 CABasicAnimations 以及 UIView > 在我将所有动画实现为 CABasicaAnimations 之后添加一些 UIView 动画,我原以为不会暂停,但它们也不起作用。 这是相关链接

我想暂停整个视图,因此我传递了 self.view.layer 作为要暂停的图层。但对于那些不了解CALayer的人,请传入您想要暂停的view.layer。每个 UIView 都有一个 CALayer,因此只需传入与您相关的最上面的 view.layer 即可。对于 Thomas 来说,根据您自己的回答,您似乎希望传入 self.containerView.layer 来暂停。

之所以有效,是因为 UIView 动画只是核心动画之上的一层。至少这是我的理解。

希望这可以帮助未来想知道如何暂停动画的人。

Actually, you can still pause the UIView animations based on the answer to the question that Vladimir linked to as it pause my CABasicAnimations as well as my UIView animations after I had implemented all my animations as CABasicaAnimations and then added some UIView animations afterwards that I had thought wouldn't be paused, but they didn't work either. This is the relevant link.

I wanted to pause my whole view so I passed self.view.layer as the layer to be paused. But for those who don't know about CALayer's, pass in the view.layer that you want paused. Each UIView has a CALayer, so just pass in the upmost view.layer that is relevant for you. In the case of Thomas, based on your own answer, it would seem that you would want to pass in self.containerView.layer to be paused.

The reason that this works is because UIView animations are simply a layer on top of Core Animation. At least that's my understanding.

Hope this helps future people wondering how to pause animations.

不再让梦枯萎 2024-09-16 02:54:31

弗拉基米尔,关于 CAAnimations 的问题是有道理的..但我找到了一种“暂停”的方法,这样我就可以继续使用 UIView 动画:

CALayer *pLayer = [self.containerView.layer presentationLayer];
CGRect frameStop = pLayer.frame;
pausedX = frameStop.origin.x;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.01];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];     
// set view properties

frameStop.origin.x = pausedX;
self.containerView.frame = frameStop;
[UIView commitAnimations];

我在这里所做的是使用presentationLayer 找出动画视图的当前 x 值。之后我执行一个新的动画来覆盖原始动画。确保为此设置 setAnimationBeginsFromCurrentstate:YES。这会取消原始动画,并将动画视图放置在动画过程的当前位置,而不是其目标位置(它会自动执行)。

希望这对其他人也有帮助! :)

Vladimir, the question about CAAnimations make sense.. but I found a way to 'pause' so I could keep using UIView animations:

CALayer *pLayer = [self.containerView.layer presentationLayer];
CGRect frameStop = pLayer.frame;
pausedX = frameStop.origin.x;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.01];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];     
// set view properties

frameStop.origin.x = pausedX;
self.containerView.frame = frameStop;
[UIView commitAnimations];

What I'm doing here is using the presentationLayer to find out current x value of the animated view. After that I execute a new animation which overwrites the original animation. Make sure to setAnimationBeginsFromCurrentstate:YES for this. This cancels the original animation and puts the animated view not to it's destination position (which it does automatically ) but at the current position of the animation proces..

Hope this helps others too! :)

行雁书 2024-09-16 02:54:31

我不确定是否可以直接使用 UIView,但你绝对可以使用动画视图的 CALayers 来代替。请参阅关于暂停和恢复 CAAnimations 的此问题

I'm not sure if it is possible with UIView's directly but you definitely can do that animating view's CALayers instead. See this question about pausing and resuming of CAAnimations.

つ低調成傷 2024-09-16 02:54:31

希望它能帮助你。

- (void)goUP{
    CFTimeInterval pausedTime = [self.layer timeOffset];
    self.layer.speed = 1.0;
    self.layer.timeOffset = 0.0;
    self.layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    self.layer.beginTime = timeSincePause;
}

- (void)goDown{
    CFTimeInterval pausedTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    self.layer.speed = 0.0;
    self.layer.timeOffset = pausedTime;
}

当您调用图层动画时,它将影响所有图层树和子模式图层动画。

Hope it will help you.

- (void)goUP{
    CFTimeInterval pausedTime = [self.layer timeOffset];
    self.layer.speed = 1.0;
    self.layer.timeOffset = 0.0;
    self.layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    self.layer.beginTime = timeSincePause;
}

- (void)goDown{
    CFTimeInterval pausedTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    self.layer.speed = 0.0;
    self.layer.timeOffset = pausedTime;
}

When you call the Layer animate, it will effect all layer tree and submode layer animate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文