2012-02-01 77 views
14

我有一個放置在UIScrollView中的UIImageView,基本上這個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-shrolling) – 2012-02-01 04:24:57

回答

51

iOS應用程序在NSRunLoop上運行。每個NSRunLoop對於不同的任務都有不同的執行模式。例如,默認的nstimer計劃在NSRunLoop上的NSDefaultRunMode下運行。然而,這意味着某些UIEvents,scrollviewing是一個,會中斷計時器,並且在事件停止更新後立即將其放置到隊列中。在你的情況,爲了得到定時器不被打斷,你需要以安排不同的模式,即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 2013-06-25 15:51:53

+2

嘿@GregPrice。感謝解釋,甚至3年之後。然而,文檔說'scheduledTimerWithTimeInterval:...'創建一個計時器,並*在默認模式下的當前運行循環*上安排它。那麼爲什麼你在默認的RunLoop中添加兩次,而不是在'NSRunLoopCommonModes'模式下添加一次呢? – Martin 2015-05-20 12:00:48

+0

'UIScrollView'運行'UITrackingRunLoopMode'中的運行循環,它與'NSDefaultRunLoopMode'不同。如果您還希望它以其他模式運行,那麼將計時器設置爲默認模式是不夠的。 – 2016-03-09 22:38:52