2012-02-01 11 views
14

मैं एक UIImageView UIScrollView में रखा है, मूल रूप से इस UIImageView बहुत बड़ा नक्शा रखती है, और "तीर" के साथ एक पूर्वनिर्धारित मार्ग पर एनिमेशन बनाया बताया नेविगेशन दिशा।NSTimer निकाल नहीं जब UIScrollView घटना होती है

लेकिन, जब भी 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 एनएसटीमर को रोकता है] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/7059366/uiscrollview-pauses-nstimer-while-scrolling) –

उत्तर

51

आईओएस अनुप्रयोग एनएसआरनलूप पर चलते हैं। प्रत्येक NSRunLoop में विभिन्न कार्यों के निष्पादन के विभिन्न तरीके होते हैं। उदाहरण के लिए, NSRunLoop पर NSDefaultRunMode के अंतर्गत डिफ़ॉल्ट nstimer चलाने के लिए निर्धारित है। क्या यह मतलब है कि हालांकि कुछ 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

+2

हे @ ग्रेग्राइस। स्पष्टीकरण के लिए धन्यवाद, यहां तक ​​कि 3 साल बाद भी। हालांकि, डॉक्टर का कहना है कि 'निर्धारित टाइमर विथटाइम इंटरवल: ...' एक टाइमर बनाता है और * इसे डिफ़ॉल्ट मोड * में वर्तमान रन लूप पर शेड्यूल करता है। तो क्यों आप इसे दो बार डिफ़ॉल्ट RunLoop में सिर्फ एक बार 'NSRunLoopCommonModes' मोड में जोड़ सकता हूँ, है ना? – Martin

+0

'UIScrollView'' UITrackingRunLoopMode' में रन लूप चलाता है, जो 'NSDefaultRunLoopMode' से अलग है। यदि आप इसे अन्य मोड में भी चलाने के लिए चाहते हैं तो डिफ़ॉल्ट मोड के लिए टाइमर शेड्यूल करना पर्याप्त नहीं है। –

संबंधित मुद्दे