2010-12-23 19 views
20

हम अपने iPhone एप्लिकेशन में एक UITabBar उपयोग करना चाहता था, लेकिन एक अपवाद के साथ: हम एक "सिंक" बटन जो मैं जबकि समन्वयन कार्रवाई हो रहा है बारी बारी से करना चाहता था की है।कोर एनिमेशन CALayer मुखौटा एनीमेशन प्रदर्शन

alt text

दुर्भाग्य से यह एक कस्टम टैब बार बनाने के लिए होने का मतलब है, लेकिन है कि न तो यहाँ और न ही वहाँ है: एनीमेशन मैं कोर एनिमेशन का उपयोग कर कार्यान्वित भयानक लग रहा है। समस्या यह है कि जबकि एनिमेट, यह प्रतिकूल सब कुछ स्क्रीन पर एनीमेशन का उपयोग कर के प्रदर्शन को प्रभावित करता है: UITableView स्क्रॉल, MKMapView पैनिंग और पिन बूँदें, आदि मेरे परीक्षण उपकरण एक iPhone 4.

समस्या कैसे हो रहा है है मैं टैब बार क्रियान्वित किया है - मैं बहुत UITabBar है, जहां आप बस आइकन के लिए एक PNG आपूर्ति करने के लिए कुछ इसी तरह प्राप्त करने के लिए चाहता था और यह एक पृष्ठभूमि छवि मास्किंग द्वारा सामान्य और प्रकाश डाला राज्यों बनाने के लिए अल्फ़ा चैनल का उपयोग करता है।

// Inside a UIView subclass' init method... 

// Create the mask layer by settings its contents as our PNG icon. 
CALayer *maskLayer = [CALayer layer]; 
maskLayer.frame = CGRectMake(0, 0, 31, 31); 
maskLayer.contentsGravity = kCAGravityCenter; 
maskLayer.contentsScale = [[UIScreen mainScreen] scale]; 
maskLayer.rasterizationScale = [[UIScreen mainScreen] scale]; 
maskLayer.contents = (id)symbolImage.CGImage; 
maskLayer.shouldRasterize = YES; 
maskLayer.opaque = YES; 

fgLayer = [[CALayer layer] retain]; 
fgLayer.frame = self.layer.frame; 
fgLayer.backgroundColor = [UIColor colorWithImageNamed:@"tabbar-normal-bg.png"].CGColor; 
fgLayer.mask = maskLayer; // Apply the mask 
fgLayer.shouldRasterize = YES; 
fgLayer.opaque = YES; 

[self.layer addSublayer:fgLayer]; 

(नोट:: मैं CALayer के mask संपत्ति के साथ इस पूरा स्क्रीनशॉट में ऊपर आप देख सकते हैं मैं भी एक छाया परत चुके हैं, लेकिन सादगी के लिए मैं हटाया कोड से मैं से छाया परत निकाल दिए हैं। । समन्वय आइकन जब यह, एनिमेट है तो यह प्रासंगिक नहीं होना चाहिए)

चेतन करने के लिए, मैं बस मुखौटा परत बारी बारी से:

- (void)startAnimating { 
    CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath: @"transform"]; 
    CATransform3D transform = CATransform3DMakeRotation(RADIANS(179.9), 0.0, 0.0, 1.0); 
    animation.toValue = [NSValue valueWithCATransform3D:transform]; 
    animation.duration = 5; 
    animation.repeatCount = 10000; 
    animation.removedOnCompletion = YES; 
    [fgLayer.mask addAnimation:animation forKey:@"rotate"]; // Add animation to the mask 
} 

तो यह सब प्रदर्शन के अलावा महान काम करता है। आप देख सकते हैं मैं पहले से ही सुझावों को Google पर चला कि rasterizing परतों/उन्हें अपारदर्शी बनाने के बारे में की कोशिश की है - नहीं मदद की है।

मुझे लगता है कि मैं अपराधी होने के रूप में मुखौटा परत की पहचान की है। जब मैं मुखौटा परत बाहर ले जाना और सिर्फ अपनी मुखौटा के बजाय fgLayer घुमाने के लिए, प्रदर्शन, अद्भुत है यह निश्चित रूप से है को प्रभावित नहीं मैं के लिए जा रहा हूँ, हालांकि:

alt text

प्रदर्शन भी बस के रूप में पहले की तरह खराब है अगर मैं मुखौटा के बजाय fgLayer बारी बारी से जबकि मुखौटा लागू किया जाता है।

तो यदि मास्क को फिर से सम्मिलित करना है तो एनीमेशन के प्रत्येक फ्रेम धीमे हो जाते हैं, क्या ऐसी कोई अन्य तकनीक है जिसका उपयोग मैं इसी तरह के प्रभाव को प्राप्त करने के लिए कर सकता हूं जिससे बेहतर प्रदर्शन होगा? मुखौटा परत के लिए एक छवि के बजाय पथ का उपयोग करना? या क्या मुझे ओपनजीएल या कुछ अच्छा प्रदर्शन करने के लिए कुछ छोड़ना होगा?

अद्यतन: आगे विचार है कि मुखौटा मंदी है मजबूत, मेरे सहकर्मी सामग्री के रूप में सिर्फ छवि के साथ एक CALayer बारी बारी से करने की कोशिश कर सुझाव दिया - तो w/oa मुखौटा ऊपर मेरी उदाहरण की तरह - और प्रदर्शन उस तरह से भी अच्छा था। तो मैं वास्तव में केवल एक ठोस रंग कर सकता हूं (कोई ढाल नहीं), लेकिन यह एक अच्छा अंतरिम समाधान हो सकता है। मैं अभी भी अच्छा प्रदर्शन हालांकि साथ एक मुखौटा घूर्णन प्राप्त करने के लिए,

तुम क्यों एक लेयर मास्क का उपयोग करने की आवश्यकता है अच्छा लगेगा तो सुझावों का स्वागत करते :)

उत्तर

15

ब्रेंट,? क्या आप अपनी मास्क परत को एक उपन्यास में परिवर्तित नहीं कर सकते? आपको बस यह सुनिश्चित करने की आवश्यकता होगी कि आपकी छवि का उचित अल्फा था और आप उस परत की सामग्री के रूप में CGImageRef का उपयोग करेंगे।

एक और बात।मुझे अभी तक पता नहीं चला है कि क्यों, लेकिन जब मैंने आवेदन किया है तो मैंने प्रदर्शन परतों को भी देखा है, केवल शीर्ष परत की बजाय प्रत्येक परत पर रास्टराइज करना चाहिए। आप देख सकते हैं कि setShouldRasterize के संदर्भ को हटा रहा है: आपकी मास्क परत में हाँ सभी मदद करता है।

+0

आपके उत्तर का दूसरा भाग समाधान था - मुझे उपन्यासियों की बजाय शीर्ष परत पर 'कंधा बनाना' सेट करना चाहिए था। ऐसा लगता है कि मास्क के बिना उतना अच्छा प्रदर्शन किया गया है। मास्क की "ज़रूरत" का कारण यह है कि मैं दृश्य रुचि जोड़ने के लिए एक साधारण ढाल वाले सरल पीएनजी आइकन "भर" सकता हूं। डिफ़ॉल्ट UITabBar यह करता है, इसलिए मैं वही करना चाहता था (लेकिन पीले रंग के साथ)। –

+0

कूल, ब्रेंट। खुशी है कि यह इतना आसान था। यदि आप इस मामले के * क्यों * में कोई अंतर्दृष्टि प्राप्त करते हैं, तो मुझे जानना अच्छा लगेगा। ;-) –

+0

मुझे यह जानना अच्छा लगेगा कि क्यों। इसके अलावा, मुझे यह जानना अच्छा लगेगा कि कैसे * शीर्ष परत को रास्टराइज करना वास्तव में मास्क एनीमेशन के प्रदर्शन में सुधार करता है। यह अभी भी वही कर रहा है जो मैं चाहता हूं - बैकिंग ग्रेडियेंट छवि स्थिर रह रही है, जबकि मुखौटा घूर्णन कर रहा है। एनीमेशन शुरू होने से पहले क्या यह वास्तव में प्रत्येक फ्रेम के लिए बिटमैप को प्रीकंप्यूटिंग कर रहा है? जादू की तरह लगता है। इस मामले में, मुझे जादू पसंद है। :) –

7

एक दृष्टिकोण आपके मास्क के रूप में उपयोग करने के लिए CAShapeLayer बनाने के लिए होगा - आपके पास बेजियर पथों के साथ आपके "सिंक" आइकन का संस्करण बनाने के लिए थोड़ा सा काम किया जाएगा, लेकिन आकार परतों में बहुत अधिक खर्च होता है बिटमैप वाले लोगों की तुलना में कम प्रदर्शन लागत प्रति रूपांतरण। दुर्भाग्यवश, आप यह सुनिश्चित नहीं कर सकते कि रोटेशन वह जगह है जहां प्रदर्शन समस्या आ रही है-यह मास्किंग बहुत अधिक हो सकती है जिससे अधिकांश अंतराल होता है, इस मामले में आप छोटे लाभ के लिए वेक्टरिंग कर चुके होंगे।

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

+2

उत्तर के लिए धन्यवाद - एनीमेशन की एक फिल्मस्ट्रिप का उपयोग करके निश्चित रूप से कुछ ऐसा था जो मैं विचार कर रहा था, लेकिन बहुत सारे काम + फ़ाइल स्पेस की तरह लग रहा था। लगता है कि * सुपरलेयर * पर सौभाग्य से 'कंधा' को लगता है कि मुझे अपेक्षित प्रदर्शन प्राप्त हुआ है। –

+0

उत्तर से, लगता है कि "सेट को कस्टरास्टरइज़ टू नो" आपकी समस्या हल हो गई है। – Shuo

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