当uiscrollview事件发生时,NSTimer不会被触发 [英] NSTimer not fired when uiscrollview event occurs

查看:136
本文介绍了当uiscrollview事件发生时,NSTimer不会被触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在UIScrollView中放置了一个UIImageView,基本上这个UIImageView拥有非常大的地图,并在预定义的路径上用箭头指向导航方向创建动画。

I have a UIImageView placed in UIScrollView, Basicly this UIImageView holds very big map, and created animation on a predefined path with "arrows" pointed navigation direction.

但是,每当uiscrollevents发生时,我认为MainLoop冻结并且NSTimer没有被触发,并且动画停止了。

But, whenever uiscrollevents occurs, I think MainLoop freezes and NSTimer being not fired, and animation stopped.

在UIScrollView,CAKeyFrameAnimation或NSTimer上是否存在解决此问题的现有属性?

Are there any existing property, which solves this problem, on UIScrollView, CAKeyFrameAnimation or 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"];
}


推荐答案

iOS应用程序在NSRunLoop上运行。每个NSRunLoop对不同的任务都有不同的执行模式。例如,默认的nstimer计划在NSRunLoop上的NSDefaultRunMode下运行。然而,这意味着某些UIEvents,scrollviewing为1,将中断计时器,并在事件停止更新时将其置于队列中以便运行。在您的情况下,为了使计时器不被中断,您需要将其安排为不同的模式,即NSRunLoopCommonModes,如下所示:

iOS Applications run on an NSRunLoop. Each NSRunLoop has different modes of execution for different tasks. For example, the default nstimer is scheduled to run under the NSDefaultRunMode on the NSRunLoop. What this means however is that certain UIEvents, scrollviewing being one, will interrupt the timer, and place it on a queue to be run as soon as the event stops updating. In your case, in order to get the timer to not be interrupted, you need to schedule it for a different mode, namely NSRunLoopCommonModes, like so:

  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
在底部,您将看到可供选择的模式的定义。另外,传说中有它,你可以编写自己的自定义模式,但很少有人曾经生活过,不敢告诉这个故事。

This mode will allow your timer to not be interrupted by scrolling. You can find more about this info here: https://developer.apple.com/documentation/foundation/nsrunloop At the bottom you will see the definitions of the modes you can choose from. Also, legend has it, you can write your own custom modes, but few have ever lived to tell the tale im afraid.

这篇关于当uiscrollview事件发生时,NSTimer不会被触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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