将新的视图控制器推入堆栈后,UIView动画继续运行 [英] UIView animation continues to run after a new view controller is pushed onto the stack

查看:55
本文介绍了将新的视图控制器推入堆栈后,UIView动画继续运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已解决.可笑的尴尬.我没有使用实例变量,而是在实现中的花括号之外声明了它.

真的很挣扎.我有一个视图控制器,用于管理动画倒数计时器.该动画使用递归UIView动画和一个递减的简单int ivar.类似于以下内容(这是一个简化的代码段):

Really struggling. I have a view controller that manages an animated countdown timer. The animation is using recursive UIView animation and a simple int ivar that gets decremented. Something like the following (this is a simplified snippet):

- (void) animate {
  [UIView animateWithDuration:0.75f
                        delay:0.25f
                      options:UIViewAnimationCurveEaseInOut
                   animations:^{ aView.center = newCenter;
                               counter--; } 
                   completion:^(BOOL finished) {
                            if (counter != 0) [self animate]; }];
}

在倒计时过程中,用户可以滑动以转到下一步,而不必等待计时器完成倒计时.当用户滑动新的视图控制器(当前视图控制器的新实例)时,将其值与下一步的值一起推入堆栈:

During the countdown the user can swipe to go to the next step rather than wait for the timer to finish the countdown. When the user swipes a new view controller -- a new instance of the current view controller -- is pushed on the stack with the values for the next step:

TimerViewController * vc = (TimerViewController*)[self.storyboard instantiateViewControllerWithIdentifier:@"Timer"];
[vc setTask: _task + 1];
[self.navigationController pushViewController:vc animated:YES];

新的视图控制器滑入到位并开始倒计时,但是以前的视图控制器仍在进行动画处理,在调试器中,我可以清楚地看到该视图控制器的另一个实例,我将弹出该实例以返回到该实例.仍在运行其动画,这会导致aView不规则地移动.两个不同的视图控制器实例正在为同一个aView实例设置动画?

The new view controller slides into place and begins to countdown, but the previous view controller continues to animate, in the debugger I can clearly see the other instance of this view controller, the one I would pop to get back to, is still running its animation, which causes aView to move erratically. The two different view controller instances are animating the same aView instance?

如何从堆栈中的上一个视图控制器停止动画?我在 viewWillDisappear 中设置了 counter = 0 ,而其他各种绝望的事情都无济于事,我错过了这里真正发挥作用的地方.

How can I stop the animation from the previous view controller in the stack? I am setting counter = 0 in viewWillDisappear and all kinds of other desperate things to no avail, I am missing what is really at play here.

非常感谢您的帮助.

更新1 (添加 viewWillDisappear 实现):

-(void) viewWillDisappear:(BOOL)animated {
   [super viewWillDisappear:animated];
   counter = 0;
}

更新2(已编辑以显示实例)

我证实了明显的事实,即存在多个带​​有各自的aView实例的TimerViewController实例.我在 animations 块中添加了日志记录,以显示当前实例,任务和计数器值.

I verified the obvious, that there are multiple TimerViewController instances with their own aView instances. I added logging during the animations block to show the current instance, task and counter values.

2012-11-03 10:28:19.930 develop.[4362:907] [0x1f5a38f0]NiceTimer:viewWillAppear
2012-11-03 10:28:19.940 develop.[4362:907] [0x1f5a38f0](0)>03:00
2012-11-03 10:28:21.149 develop.[4362:907] [0x1f5a38f0](0)>02:59
2012-11-03 10:28:22.161 develop.[4362:907] [0x1f5a38f0](0)>02:58
2012-11-03 10:28:23.170 develop.[4362:907] [0x1f5a38f0](0)>02:57
2012-11-03 10:28:24.183 develop.[4362:907] [0x1f5a38f0](0)>02:56
2012-11-03 10:28:25.210 develop.[4362:907] [0x1f5a38f0](0)>02:55
2012-11-03 10:28:26.221 develop.[4362:907] [0x1f5a38f0](0)>02:54
2012-11-03 10:28:26.694 develop.[4362:907] ---swipe---
2012-11-03 10:28:26.698 develop.[4362:907] delegate:niceTimerViewControllerDidSwipe:duringTask
2012-11-03 10:28:26.713 develop.[4362:907] [0x1f5a38f0]NiceTimer:viewWillDisappear
2012-11-03 10:28:26.715 develop.[4362:907] [0x1f5b0ac0]NiceTimer:viewWillAppear
2012-11-03 10:28:26.720 develop.[4362:907] [0x1f5b0ac0](1)>02:00
2012-11-03 10:28:27.096 develop.[4362:907] [0x1f5a38f0]NiceTimer:viewDidDisappear
2012-11-03 10:28:27.099 develop.[4362:907] [0x1f5a38f0](0)>01:59
2012-11-03 10:28:27.748 develop.[4362:907] [0x1f5b0ac0](1)>01:58
2012-11-03 10:28:27.754 develop.[4362:907] [0x1f5a38f0](0)>01:57
2012-11-03 10:28:28.754 develop.[4362:907] [0x1f5b0ac0](1)>01:56
2012-11-03 10:28:28.763 develop.[4362:907] [0x1f5a38f0](0)>01:55
2012-11-03 10:28:29.764 develop.[4362:907] [0x1f5b0ac0](1)>01:54
2012-11-03 10:28:29.770 develop.[4362:907] [0x1f5a38f0](0)>01:53
2012-11-03 10:28:30.542 develop.[4362:907] ---swipe---
2012-11-03 10:28:30.545 develop.[4362:907] delegate:niceTimerViewControllerDidSwipe:duringTask:1
2012-11-03 10:28:30.560 develop.[4362:907] [0x1f5b0ac0]NiceTimer:viewWillDisappear
2012-11-03 10:28:30.562 develop.[4362:907] [0x1f5ac3d0]NiceTimer:viewWillAppear
2012-11-03 10:28:30.567 develop.[4362:907] [0x1f5ac3d0](2)>05:00
2012-11-03 10:28:30.593 develop.[4362:907] [0x1f5a38f0](0)>04:59
2012-11-03 10:28:30.601 develop.[4362:907] [0x1f5a38f0](0)>04:58
2012-11-03 10:28:30.617 develop.[4362:907] [0x1f5a38f0](0)>04:57
2012-11-03 10:28:30.620 develop.[4362:907] [0x1f5a38f0](0)>04:56

很久很抱歉,但这确实显示了正在发生的事情.滑动后,即可进行推送(帖子顶部的代码).我希望任务增加(0)>转到(1)>并保持不变,直到下一次滑动.相反,我看到堆栈中的每个先前实例都使用当前计数器的值继续触发.每个上一个实例的动画在当前计数器上继续播放

Sorry for so long but this really shows what is going on. After a swipe there is the push (code at the top of the post). I would expect the task to increment (0)> go to (1)> and remain constant until the next swipe. Instead I am seeing each previous instance on the stack continue to fire, using the value of the current counter. Each previous instance's animation continues against the current counter

更新3

我实现了一个在滑动处理程序中调用的委托,TVC1是在推送时传递给TVC2等的委托.委托将counter设置为0,称为removeAllAnimations等,并且无效.我真的以为这样可以做到.在这一点上,我认为我正在尝试以错误的方式解决问题的错误方法.创建了一个新项目,简单的实现,以确保它不是应用程序中的其他内容.

I implemented a delegate that gets called in the swipe handler, TVC1 is the delegate that gets passed to TVC2, etc, when pushed. The delegate sets counter to 0, called removeAllAnimations, etc, and no effect. I really thought this would do it. At this point I think I am going down the wrong path trying to solve it in the manner. Made a new project, trivial implementation, to make sure it wasn't something else in the app.

-(void)timerViewControllerDidSwipe:(TimerViewController *)controller duringTask:(int)task {

    NSLog(@"timerViewControllerDidSwipe:duringTask:%d", task);
    counter = 0;
    [self.aView.layer removeAllAnimations];
    [self.view.layer removeAllAnimations];
    aView = nil;

    // This is showing everything I tried
}

更新4

我发现了问题!所有实例都引用同一个int.我不知道这怎么可能,整数不是特定于类的实例的?

I found the issue! All instances refer to the same int. I don't know how this is possible, ints are not specific to an instance of a class??

2012-11-03 13:16:49.336 develop.[4656:907] [animate:0x1ed8c790](1)>02:46
2012-11-03 13:16:49.340 develop.[4656:907] **[^anim:0x1ed8c790](1)>166(duration=0x6a748)**
2012-11-03 13:16:49.344 develop.[4656:907] [^after:0x1eddb8c0](0)>166
2012-11-03 13:16:49.352 develop.[4656:907] [animate:0x1eddb8c0](0)>02:45
2012-11-03 13:16:49.356 develop.[4656:907] **[^anim:0x1eddb8c0](0)>165(duration=0x6a748)**

推荐答案

已修复.不能再尴尬了.基本语法问题.我没有将变量声明括在花括号内.我是这样做的:

Fixed. Could not be more embarrassed. Basic syntax issue. I did not enclose the variable declarations within curly braces. I did this:

@implementation TimerViewController 

int counter;

- (void) aMethod { }

@end

代替此:

@implementation TimerViewController {

int counter;

}

- (void) aMethod { }

@end

我希望我的错误会对某人有所帮助!对我而言,这是永远不会发生的.我不会再犯一个错误.

I hope my error will help someone! It never would have occurred to me. A mistake I will not make again.

这篇关于将新的视图控制器推入堆栈后,UIView动画继续运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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