我在UIScrollView中放置了一个UIImageView,基本上这个UIImageView拥有非常大的地图,并在预定义的路径上用“箭头”指向导航方向创建动画。
但是,每当发生uiscrollevents时,我认为MainLoop冻结并且NSTimer没有被触发,并且动画停止了。
在UIScrollView,CAKeyFrameAnimation或NSTimer上是否存在解决此问题的现有属性?
//viewDidLoad
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(drawLines:) userInfo:nil repeats:YES];
- (void)drawLines:(NSTimer *)timer {
CALayer *arrow = [CALayer layer];
arrow.bounds = CGRectMake(0, 0, 5, 5);
arrow.position = CGPointMake(line.x1, line.y1);
arrow.contents = (id)([UIImage imageNamed:@"arrow.png"].CGImage);
[self.contentView.layer addSublayer:arrow];
CAKeyframeAnimation* animation = [CAKeyframeAnimation animation];
animation.path = path;
animation.duration = 1.0;
animation.rotationMode = kCAAnimationRotateAuto; // object auto rotates to follow the path
animation.repeatCount = 1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.fillMode = kCAFillModeForwards;
[arrow addAnimation:animation forKey:@"position"];
}
答案 0 :(得分:55)
iOS应用程序在NSRunLoop上运行。每个NSRunLoop对不同的任务都有不同的执行模式。例如,默认的nstimer计划在NSRunLoop上的NSDefaultRunMode下运行。然而,这意味着某些UIEvents,scrollviewing为1,将中断计时器,并在事件停止更新时将其置于队列中以便运行。在您的情况下,为了使计时器不被中断,您需要将其安排为不同的模式,即NSRunLoopCommonModes,如下所示:
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:280
target:self
selector:@selector(doStuff)
userInfo:nil
repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:self.myTimer forMode:NSRunLoopCommonModes];
此模式将允许您的计时器不会被滚动中断。 您可以在此处找到有关此信息的更多信息:https://developer.apple.com/documentation/foundation/nsrunloop 在底部,您将看到可以选择的模式的定义。另外,传说中有它,你可以编写自己的自定义模式,但很少有人曾经生活过,不敢告诉这个故事。
答案 1 :(得分:0)
又一件事(c)
所以:
self.myTimer = [NSTimer timerWithTimeInterval:280目标:自我选择器:@selector(doStuff)userInfo:无重复:NO]; [[NSRunLoop mainRunLoop] addTimer:self.myTimer forMode:NSRunLoopCommonModes];