2011-02-02 4 views
22

पर खींचा जाता है। मेरे पास एक एनिमेटेड पारदर्शी ओपनजीएल ईएस सबव्यूव (ऐप्पल के टेम्पलेट ईएजीएलवीव क्लास का एक संशोधन) है जो एक घूर्णन क्षेत्र खींचता है। ऐप्पल के उदाहरण की तरह, CADisplayLink का उपयोग उन उपकरणों पर किया जाता है जहां उपलब्ध हैं।ओपनजीएल ईएस व्यू में एनीमेशन फ्रीज करता है जब यूआईएसक्रॉल व्यू आईफोन

उसी स्क्रीन पर, UIScrollView में UIButtons शामिल हैं जिन्हें चुना जा सकता है। जब उपयोगकर्ता UIScrollView को स्क्रॉल करता है, तो मेरे EAGLView की एनीमेशन फ्रीज होती है। यह व्यवहार आईओएस सिम्युलेटर 4.2 और आईफोन 2 जी डिवाइस पर आईफोन ओएस 3.1.3 पर पुन: उत्पन्न होता है।

EAGLView के विराम को रोकने के लिए क्या करना है, इसके बारे में कोई विचार, मेरे स्वयं के स्क्रॉल व्यू कोडिंग के अलावा?

+0

2016 - ऐसा नहीं है कि प्रतीत होता है ** commonModes ** वास्तव में विशिष्ट आधुनिक iOS के लिए समाधान है।। देखें: http://stackoverflow.com/a/4878182/294884 यह काफी अविश्वसनीय है कि इस पर पांच साल तक कोई क्यूए नहीं रहा है। – Fattie

उत्तर

51

चाहे CADisplayLink स्क्रॉल के दौरान आग लगती है उस मोड पर निर्भर करता है जिसके साथ आप इसे रन लूप में जोड़ते हैं। शायद आप इस किया है, कहीं न कहीं:

[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

UIApplication 'नियंत्रण में ट्रैकिंग' है, जो भी शामिल है जब एक scrollview स्क्रॉल है के लिए, एक रन पाश मोड, UITrackingRunLoopMode कहते हैं। तो उस समय रनलोप को डिफ़ॉल्ट मोड से बाहर कर दिया जाता है और इसलिए आपका डिस्प्ले लिंक (और डिफ़ॉल्ट टाइम्स में जोड़ा गया कोई भी टाइमर, NSURLConnections, आदि) डिफ़ॉल्ट मोड को पुनर्स्थापित किए जाने तक आग में विफल हो जाएगा।

त्वरित सुधार: करने के लिए अपने कोड बदलने के लिए:

[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 

UITrackingRunLoopMode आम विधियों में से एक माना जाता है।

UIKit में बाधा डालने में बहुत अधिक समय खर्च करने से कुछ बहुत ही खराब नियंत्रण प्रतिक्रिया हो सकती है, इसलिए आपको सावधान रहना होगा। यह बड़े पैमाने पर विषय से अलग हो जाएगा, लेकिन हालांकि ओपनजीएल मोडल है और इसलिए विशेष रूप से थ्रेडिंग अनुकूल नहीं है, तो आप एक अलग थ्रेड पर प्रतिपादन करने के लिए एक ईएजीएलशेयर समूह का उपयोग कर सकते हैं और फिर इसे मुख्य थ्रेड पर दबा सकते हैं।


में (2016) Swift3 एक उदाहरण ...

let d = CADisplayLink(target: self, selector: #selector(ThisClassName.updateAlpha)) 
d.add(to: RunLoop.current, forMode: RunLoopMode.commonModes) 


//and then, for example... 
func updateAlpha() { 
    let a = leader.layer.presentation()?.value(forKey: "opacity") as! CGFloat 
    follower.alpha = a 
    } 
+0

धन्यवाद! इस परियोजना के लिए, मैं वास्तव में UIKit को अवरुद्ध करने की चिंता नहीं करता, क्योंकि मैं केवल जीयूआई में एक बनावट क्षेत्र प्रस्तुत कर रहा हूं, इसलिए जीएल को UIKit प्रसंस्करण के लिए काफी समय छोड़ना चाहिए :-) –

+3

बस एक छोटा सा अतिरिक्त! हालांकि यह बहुत अच्छा काम करता है, फिर भी यह आईओएस 4 उपकरणों पर एक बग ट्रिगर करता है जहां UIScrollView कभी भी टच-अप ईवेंट नहीं पकड़ता है और स्क्रॉल मोड में फ्रीज करता है। यह आईओएस 4 सिम्युलेटर में और आईओएस 3.1.3 के साथ अपने आईफोन 2 जी पर दिखाई नहीं देता है। समाधान काफी सरल साबित हुआ: डिस्प्ले लिंक समर्थित होने पर भी मैंने एनएसटीमर आधारित कोडपैथ पर स्विच किया, और मैंने NSRunLoopCommonModes में NSTimer निर्धारित किया। –

+1

इस समाधान पर अधिक जानकारी के लिए इस प्रश्न को देखें: http://stackoverflow.com/questions/5944050/cadisplaylink-opengl-rendering-breaks-uiscrollview-behaviour –

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