2010-03-07 10 views
30

की एक कस्टम प्रॉपर्टी को एनिमेट करना मेरे पास एक कैलियर सबक्लास, माईलेयर है, जिसमें एनआईएसएनटेगर संपत्ति है जिसे MyInt कहा जाता है। मैं वास्तव में CABasicAnimation के माध्यम से इस संपत्ति को एनिमेट करना चाहता हूं, लेकिन ऐसा लगता है कि CABasicAnimation केवल तथाकथित "एनिमेटेबल" गुणों (सीमाओं, स्थिति, आदि) पर काम करता है। क्या कोई ऐसी चीज है जो मैं अपनी कस्टम myInt संपत्ति को एनिमेट करने योग्य बनाने के लिए ओवरराइड कर सकता हूं?कैलियर सबक्लास

+1

उस संपत्ति को 'फ्लोट' बनाने का प्रयास करें? – kennytm

उत्तर

68

हां, यह संभव है (केवल नवीनतम कोर एनीमेशन रिलीज में, मुझे विश्वास है, यानी आईफोन 3.0+ और ओएस एक्स 10.6+)।

  1. अपनी संपत्ति गतिशील बनाएं, ताकि CA आप के लिए accessors लागू करता है:

    @dynamic myInt; 
    
  2. बताएँ परत है कि संपत्ति के परिवर्तन redrawing की आवश्यकता होती है:

    + (BOOL)needsDisplayForKey:(NSString*)key { 
        if ([key isEqualToString:@"myInt"]) { 
         return YES; 
        } else { 
         return [super needsDisplayForKey:key]; 
        } 
    } 
    
  3. उपयोग मूल्य myInt की drawInContext: विधि में। अब, जब आप myInt को एनिमेट करते हैं, तो कोर एनीमेशन एनीमेशन के प्रत्येक चरण के लिए मानों को अलग करेगा और परत को खुद को आकर्षित करने के लिए बार-बार पूछेगा।

  4. यदि आप इस संपत्ति के लिए निहित एनिमेशन सक्षम करना चाहते हैं, तो actionForKey: ओवरराइड करें।

+0

धन्यवाद! यह मुझे एक समाधान के इतने करीब है कि मैं इसका स्वाद ले सकता हूं! -drawInContext: MyInt सही ढंग से interpolated के साथ कई बार कहा जाता है। दुर्भाग्यवश CGContextDrawImage() एनीमेशन चल रहा है, जबकि अब कार्य नहीं करता है। संदर्भ मैं भरता हूं या पथ जो स्ट्रोक सभी ठीक से खींचे जाते हैं, लेकिन सामान्य रूप से CGContextDrawImage() द्वारा खींची गई छवि तब तक गायब हो जाती है जब तक कि एनीमेशन खत्म नहीं हो जाता है जैसे CGContextDrawImage() को कभी नहीं कहा जाता है। मैं परेशान हूँ कोई विचार? – jemmons

+0

कोई विचार नहीं, क्षमा करें। मुझे आशा है कि आपको समाधान मिलेगा। –

+3

यह ठीक है। आप अभी भी स्टैक ओवरफ़्लो पर देखे गए सबसे अच्छे लिखित उत्तरों में से एक हैं :) – jemmons

6

वहाँ एक तरह से अपने कस्टम CALayer उपवर्गों की Ivars बनाए रखने के लिए है। आप initWithLayer को ओवरराइड करते हैं:, जिस विधि को कस्टम परतों की एक प्रति बनाने के लिए कहा जाता है। उदाहरण के लिए, यदि आप एक परत है जिसमें आप कोई कस्टम गुण 'कोण' कहा जाता है का निर्माण करना चाहते है, तो आप निम्नलिखित कोड का उपयोग कर सकता है:

@implementation AngledLayer 
@synthesize angle = _angle 

// Tell Core Animation that this key should be animated 
+ (BOOL) needsDisplayForKey:(NSString *)key 
{ 
    if ([key isEqualToString:@"angle"]) return YES; 
    return [super needsDisplayForKey:key]; 
} 


// Make sure that, when the layer is copied, so is the custom ivar 
- (id) initWithLayer:(id)layer 
{ 
    self = [super initWithLayer:layer]; 
    if (self) { 
     AngledLayer *angledVersion = (AngledLayer *)layer; 
     self.angle = angledVersion.angle; 
    } 
    return self; 
} 

और बलबीर के अपने चाचा! ध्यान दें कि आप इस ऑब्जेक्ट को निहित एनीमेशन के साथ उपयोग नहीं कर सकते हैं, जिसके लिए आपको कार्रवाई को ओवरराइड करना होगा: विधि।

+1

यह मेरे लिए काम नहीं करता है। 'InitWithLayer' के अंदर, परत हमेशा एनिमेट करते समय भी संपत्ति का प्रारंभिक मूल्य होता है। सेटर कहीं और कहा जाता है। – zakdances

+1

मैं आपके मित्रवत के समान दिख रहा हूं। जबकि initWithLayer और जरूरतों के संयोजन DisplayForkey एनीमेशन होने की अनुमति देता है, जैसे ही यह समाप्त होता है, परत वापस प्रारंभिक मान पर जाती है। मैं अभी भी एक समाधान की तलाश में हूं। –

+0

ठीक है, ऐसा लगता है कि मुझे एहसास नहीं हुआ कि @ गतिशील सेटर को स्वचालित रूप से एनिमेट करने का कारण बनता है। लेकिन अगर किसी कारण से आपको इसके लिए और अधिक करने की ज़रूरत है, तो आपको शायद अपना खुद का सेटटर बनाना होगा जिसमें इसका अपना एनीमेशन ब्लॉक हो ताकि आप एनीमेशन होने से पहले अपनी परत संपत्ति बदल सकें। देखें [लिंक] (http://stackoverflow.com/questions/11515647/objective-c-cabasicanimation-applying-changes-after-animation) –