2012-02-01 6 views
14

UIImageViewはUIScrollViewに配置されています。基本的には、このUIImageViewは非常に大きなマップを保持しており、ナビゲーション方向を示す矢印が付いた定義済みパスでアニメーションを作成します。uiscrollviewイベントが発生したときにNSTimerが起動しない

しかし、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

可能な複製[UIScrollViewはNSTimerをスクロールしながら一時停止する](http://stackoverflow.com/questions/7059366/uiscrollview-pauses-nstimer-while-scrolling) –

答えて

51

iOSアプリケーションはNSRunLoopで実行されます。各NSRunLoopは、異なるタスクに対して異なる実行モードを持っています。たとえば、デフォルトのnstimerは、NSRunLoopのNSDefaultRunModeで実行するようにスケジュールされています。しかし、これはつまり、特定のUIEvent(スクロールビューは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 ここでは、選択できるモードの定義が表示されます。また、伝説はそれを持っている、あなたは独自のカスタムモードを書くことができますが、たった今恐怖の物語を伝えるために住んでいたことはほとんどありません。

+0

素敵な説明。 – Robert

+2

ちょっと@GregPrice。 3年後の説明にも感謝します。しかし、 'scheduledTimerWithTimeInterval:...'はタイマーを作成し、それをデフォルトモード*で現在の実行ループにスケジュールします。なぜ、NSRunLoopCommonModesモードで一度だけでなく、デフォルトのRunLoopで2回追加するのですか? – Martin

+0

'UIScrollView'は、' NSDefaultRunLoopMode'とは異なる 'UITrackingRunLoopMode'で実行ループを実行します。他のモードで実行したい場合は、デフォルトモードのタイマーをスケジュールするだけでは不十分です。 –

関連する問題