2009-12-15 29 views
32

कोर एनीमेशन संदर्भ में चेन एनीमेशन के लिए सबसे सुरुचिपूर्ण और मॉड्यूलर तरीका कौन सा है?चेनिंग कोर एनीमेशन एनिमेशन

मुझे लगता है कि शुरू होता है एनिमेशन करने के लिए मतलब है जब अन्य समाप्त (उदाहरण, position और फिर opacity को बदलने के लिए) .. सामान्य दृष्टिकोण सीधे गुणों को बदलने के लिए है:

layer.position = new_point; 
layer.opacity = 0.0f; 

लेकिन यह उन्हें एक ही पर क्या करेंगे पहर। मैं एक दूसरे के लिए इंतजार करना चाहता हूँ।

और विभिन्न वस्तुओं के लिए एनिमेशन को चेन करने के बारे में क्या? मैं CATransaction के बारे में की तरह इस्तेमाल किया पढ़ा है:

[CATransaction begin] 
layer1.property = new_property; 
[CATransaction begin] 
layer2.property2 = new_property2; 
[CATransaction commit]; 
[CATransaction commit]; 

लेकिन यह काम करने के लिए प्रतीत नहीं होता ..

उत्तर

73

आप एनीमेशन समूह का भी उपयोग कर सकते हैं और एनीमेशन के स्टार्टटाइम फ़ील्ड का उपयोग कर सकते हैं। कुछ इस तरह का प्रयास करें:

CABasicAnimation *posAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; 
[posAnimation setFromValue:[NSNumber numberWithFloat:0.0]]; 
[posAnimation setToValue:[NSNumber numberWithFloat:1.0]]; 
// Here's the important part 
[posAnimation setDuration:10.0]; 
[posAnimation setBeginTime:0.0]; 

CABasicAnimation *borderWidthAnimation = [CABasicAnimation animationWithKeyPath:@"borderWidth"]; 
[borderWidthAnimation setFromValue:[NSNumber numberWithFloat:0.0]]; 
[borderWidthAnimation setToValue:[NSNumber numberWithFloat:1.0]]; 
// Here's the important part 
[borderWidthAnimation setDuration:10.0]; 
[borderWidthAnimation setBeginTime:5.0]; 

CAAnimationGroup *group = [CAAnimationGroup animation]; 
[group setDuration:10.0]; 
[group setAnimations:[NSArray arrayWithObjects:posAnimation, borderWidthAnimation, nil]]; 

[layer addAnimation:group forKey:nil]; 

सूचना है कि पूरे एनीमेशन की अवधि 10 सेकंड है। पहला व्यक्ति दूसरे 0 पर शुरू होता है और दूसरा 5 सेकंड से शुरू होता है।

+9

ध्यान दें कि यह महान है, लेकिन केवल एक ही करने के लिए लागू एनिमेशन के लिए काम करेंगे परत। – nielsbot

+0

यदि आप पहली एनीमेशन समाप्त होने के तुरंत बाद एक विधि को कॉल करना चाहते हैं, तो आप नहीं कर सकते हैं। एनीमेशनडिडस्टॉप केवल तभी कॉल किया जाता है जब पूरा समूह समाप्त हो जाता है। – durazno

+0

कुंजी पथ '" स्थिति "' एक 'CGPoint' है जिसे' NSValue' ('NSNumber' नहीं) के साथ एन्कोड किया जाना आवश्यक है। – wcochran

0

मैं नहीं मानता कि आप कर सकते हैं "घोंसला" सीए आप अपने उदाहरण में है के रूप में एनिमेशन।

आपको एनीमेशन के लिए प्रतिनिधि निर्दिष्ट करने और प्रतिनिधि के चयनकर्ता animationDidStop:finished: के भीतर अपना दूसरा "संक्रमण" डालना होगा।

शायद ऐप्पल के Animation Types & Timing Programming Guide पर एक नज़र डालना चाहें।

5

जैसा मैट ने इंगित किया है, आप एनीमेशन समूह बना सकते हैं जिसमें अलग-अलग प्रारंभिक समय के साथ एक ही परत के लिए विभिन्न एनिमेशन शामिल होते हैं। तुम भी स्टैंड-अलोन CAAnimation वस्तुओं या CAAnimation समूह के लिए एक प्रतिनिधि सेट कर सकते हैं और के रूप में प्रत्येक एनीमेशन खत्म यह (एक animationDidStop:finished: प्रतिनिधि विधि कॉल करेंगे ध्यान दें कि एनिमेशन है कि एक समूह का हिस्सा हैं उनके प्रतिनिधि के animationDidStop:finished: विधि कॉल नहीं होंगे।

मैंने एक अच्छी चाल का पता लगाया जो CAAnimation animationDidStop:finished: विधि का उपयोग अधिक शक्तिशाली बनाता है। मैं कुंजी @ "एनीमेशन कॉम्प्लेक्शनब्लॉक" के साथ स्टैंड-अलोन एनीमेशन या एनीमेशन समूह में कोड का एक ब्लॉक जोड़ने के लिए setValue:forKey: विधि का उपयोग करता हूं। फिर मैं एक सामान्य animationDidStop:finished: लिखता हूं विधि जो @ "एनीमेशन कॉम्प्लेक्शनब्लॉक" कुंजी के लिए पूर्ण-पूर्ण एनीमेशन की जांच करती है, और यदि इसे पाती है, तो कोड के ब्लॉक को निष्पादित करें।

है कि तकनीक की एक काम उदाहरण के लिए GitHub पर इस परियोजना पर एक नज़र डालें:

CAAnimation demo with completion blocks

आप एक भी एक

[CATransaction begin]; 
//... 
[[CATransaction commit]; 

ब्लॉक के अंदर एनिमेशन के एक समूह सेट के रूप में आप का सुझाव दिया। जब आप ऐसा करते हैं, तो आप वर्तमान लेनदेन समूह में सभी एनिमेशन पूर्ण होने पर कोड के ब्लॉक को आमंत्रित करने के लिए CATransaction क्लास विधि setCompletionBlock: का उपयोग कर सकते हैं। एक लेनदेन के लिए समापन ब्लॉक तब अगले लेनदेन को ट्रिगर कर सकता है।

0

क्या मैं हमेशा एक एनीमेशन के शुरू और अंत समय सेट करने के लिए पसंद है अलग से यह है:

मैं A2DynamicDelegate इस्तेमाल किया (जिसका विकास अब BlocksKit -Repo में हो रहा है, कौन जानता है क्यों < _ <) करने के लिए समापन लागू करें CAAnimation पर एक श्रेणी में संपत्ति बंद करें।

यह मैं सक्षम इस तरह सामान करना है:

CAAnimation *a = ... 
CAAnimation *b = ... 
CAAnimation *c = ... 

a.completionHandler = ^{ 
    [self.layer addAnimation:b forKey:@"foo"]; 
    [self.layer addAnimation:c forKey:@"bar"]; 
}; 

बहुत अधिक लचीला :)

मैं पूरा होने हैंडलर here के लिए मेरे कोड अपलोड कर दिया है। हालांकि हेडर फ़ाइल में नोटिस पर एक नज़र डालें। मैं वास्तव में उलझन में हूं कि विधि क्यों नहीं कहा जाता है।

-1

मेरे "toolchain" सभी "चाल" सहित बिना, इस उदाहरण नहीं है सीधे प्रतिलिपि/pastable ... लेकिन यह "श्रृंखलित" एनिमेशन के लिए एक बहुत आसान रणनीति दिखाता है ..

CATransform3D trans = m34(); // define chain-wide constants. 
// Name your "stack". My "nextObject" returns arr[i]->done == nil. 
NSArray *layerStack = layer.sublayers; 
//define a block, that "takes" a layer as it's argument. 
void(^__block ChainBlock)(CALayer*) = ^(CALayer *m) { 
// animations, transforms, etc for each inividual "step". 
    [m animate:@"transform" 
      // These are just NSValue-wrapped CAT3D's 
      from:AZV3d(CATransform3DRotate(trans, 0,1,0,0)) 
      to:AZV3d(CATransform3DRotate(trans,1.5,1,0,0)) 
      time:2 // total time == each step * layerStack.count 
     eased:kCAMediaTimingFunctionEaseOut 
    completion:^{ // In completion, look for "next" layer. 
        CAL* m2 = [layers nextObject]; 
// If there is "another" layer, call this block, again... with it. 
         if (m2) chainAnis(m2); 
// Otherise,you're done. Cleanup, toggle values, whatevs. 
        else self.finishedProperty = YES; 
    }]; 
}; 
// Give the block we just defined your "first" layer. 
ChainBlock(layerStack[0]); // It will recursively feed itself. 

यह स्पष्ट रूप से कुछ "बाहरी जादू" पर निर्भर करता है, लेकिन अवधारणा सरल है, और निर्भर करता है (निर्भरताओं के माध्यम से) सकल प्रतिनिधिमंडल के किसी भी प्रकार से "निपटने" की आवश्यकता। विशेष रूप से, animate:from:to:time:easing:completion, आदि श्रेणियां महान FunSize Framework, on Github से आती हैं।

0

मैं इस पुल setCompletionBlock विधि का उपयोग कर एक बंद है कि अगले एनीमेशन जब पहले एक समाप्त हो गया है चलाता है परिभाषित करने के लिए:

[CATransaction begin] 
layer1.property = new_property; 
CATransaction.setCompletionBlock { 
    [CATransaction begin] 
    layer2.property2 = new_property2; 
    [CATransaction commit]; 
} 
[CATransaction commit]; 
संबंधित मुद्दे