2013-01-30 58 views
9

मैं सेटबीजिनटाइम का उपयोग कर परत की अस्पष्टता और स्थिति 3 एनीमेशन की स्थिति में देरी करने की कोशिश कर रहा हूं। मैंने परत बॉक्स लेयर कहा है। एनीमेशन अच्छी तरह से चल रहा है हालांकि पहले 3 सेकंड के दौरान (परत अभी तक दिखाना नहीं है) परत अपनी अंतिम स्थिति और अस्पष्टता पर प्रदर्शित होती है। यह नहीं होना चाहिए। समूह एनीमेशन इस मुद्दे को हल नहीं करता है। क्या कोई मदद कर सकता है? नीचे दिए गए कोड देखें:सीएबीएसिक एनीमेशन स्थिति और 3 सेकंड तक परत की अस्पष्टता में देरी करने की कोशिश कर रहा है लेकिन

// Create an animation that will change the opacity of a layer 
CABasicAnimation *fader = [CABasicAnimation animationWithKeyPath:@"opacity"]; 


// It will last 1 second and will be delayed by 3 seconds 
[fader setDuration:1.0]; 
[fader setBeginTime:CACurrentMediaTime()+3.0]; 


// The layer's opacity will start at 0.0 (completely transparent) 
[fader setFromValue:[NSNumber numberWithFloat:startOpacity]]; 

// And the layer will end at 1.0 (completely opaque) 
[fader setToValue:[NSNumber numberWithFloat:endOpacity]]; 

// Add it to the layer 
[boxLayer addAnimation:fader forKey:@"BigFade"]; 

// Maintain opacity to 1.0 JUST TO MAKE SURE IT DOES NOT GO BACK TO ORIGINAL OPACITY 
[boxLayer setOpacity:endOpacity]; 


// Create an animation that will change the position of a layer 
CABasicAnimation *mover = [CABasicAnimation animationWithKeyPath:@"position"]; 

// It will last 1 second and will be delayed by 3 seconds 
[mover setDuration:1.0]; 
[mover setBeginTime:CACurrentMediaTime()+3.0]; 

// Setting starting position 
[mover setFromValue:[NSValue valueWithCGPoint:CGPointMake(startX, startY)]]; 

// Setting ending position 
[mover setToValue:[NSValue valueWithCGPoint:CGPointMake(endX, endY)]]; 

// Add it to the layer 
[boxLayer addAnimation:mover forKey:@"BigMove"]; 

// Maintain the end position at 400.0 450.0 OTHERWISE IT IS GOING BACK TO ORIGINAL POSITION 
[boxLayer setPosition:CGPointMake(endX, endY)]; 
+0

कैसे की तरह एक विधि बनाने के बारे में [आत्म performSelector: @selector (methodName) withObject: afterDelay शून्य: 3.0f]; या नींद का उपयोग(); –

+0

मेरी समस्या देरी एनीमेशन नहीं है बल्कि यह तथ्य कि देरी एनीमेशन शुरू होने से पहले परत प्रदर्शित होती है। – Armand

उत्तर

17

समस्या यह है कि आप position की और उनके अंत मूल्यों के opacity की boxLayer गुण स्थापित कर रहे है। आप की जरूरत करने के लिए:

  1. उनके शुरुआती मूल्यों के boxLayer प्रॉपर्टी सेट, नहीं उनके समाप्त होने के मूल्यों (यही कारण है कि यह न खत्म होने वाली स्थिति/अस्पष्टता में शुरू होने वाले है ... आमतौर पर अगर एनीमेशन तुरंत शुरू होता है, यह नहीं है एक मुद्दा, लेकिन क्योंकि आप शुरुआत का निर्धारण कर रहे हैं, अंतिम स्थिति का उपयोग समस्याग्रस्त है);

  2. अपने दो एनिमेशन के लिए, आप kCAFillModeForwards को NO और fillMode को removedOnCompletion बदलने के लिए (यह सही तरीका इसे वापस पूरा होने पर मूल स्थिति में वापस लाने में से रखने के लिए है) है।

इस प्रकार

:

// Create an animation that will change the opacity of a layer 
CABasicAnimation *fader = [CABasicAnimation animationWithKeyPath:@"opacity"]; 

// It will last 1 second and will be delayed by 3 seconds 
[fader setDuration:1.0]; 
[fader setBeginTime:CACurrentMediaTime()+3.0]; 

// The layer's opacity will start at 0.0 (completely transparent) 
[fader setFromValue:[NSNumber numberWithFloat:startOpacity]]; 

// And the layer will end at 1.0 (completely opaque) 
[fader setToValue:[NSNumber numberWithFloat:endOpacity]]; 

// MAKE SURE IT DOESN'T CHANGE OPACITY BACK TO STARTING VALUE  
[fader setRemovedOnCompletion:NO]; 
[fader setFillMode:kCAFillModeForwards]; 

// Add it to the layer 
[boxLayer addAnimation:fader forKey:@"BigFade"]; 

// SET THE OPACITY TO THE STARTING VALUE 
[boxLayer setOpacity:startOpacity]; 

// Create an animation that will change the position of a layer 
CABasicAnimation *mover = [CABasicAnimation animationWithKeyPath:@"position"]; 

// It will last 1 second and will be delayed by 3 seconds 
[mover setDuration:1.0]; 
[mover setBeginTime:CACurrentMediaTime()+3.0]; 

// Setting starting position 
[mover setFromValue:[NSValue valueWithCGPoint:CGPointMake(startX, startY)]]; 

// Setting ending position 
[mover setToValue:[NSValue valueWithCGPoint:CGPointMake(endX, endY)]]; 

// MAKE SURE IT DOESN'T MOVE BACK TO STARTING POSITION 
[mover setRemovedOnCompletion:NO]; 
[mover setFillMode:kCAFillModeForwards]; 

// Add it to the layer 
[boxLayer addAnimation:mover forKey:@"BigMove"]; 

// SET THE POSITION TO THE STARTING POSITION 
[boxLayer setPosition:CGPointMake(startX, startY)]; 

व्यक्तिगत रूप से, मुझे लगता है कि आप कुछ है कि कहीं अधिक आसानी से प्रयोजनों के लिए (दृश्य पर ब्लॉक आधारित एनीमेशन के साथ किया जाता है के लिए बहुत काम कर रहे हैं इस प्रदर्शन के बारे में, मुझे लगता है कि boxLayerCALayer है जो box नामक नियंत्रण के लिए है)। आप क्वार्ट्ज 2 डी की जरूरत नहीं है, या तो, आप इसे इस तरह से करते हैं:

box.alpha = startOpacity; 
box.frame = CGRectMake(startX, startY, box.frame.size.width, box.frame.size.height); 

[UIView animateWithDuration:1.0 
         delay:3.0 
        options:0 
       animations:^{ 
        box.alpha = endOpacity; 
        box.frame = CGRectMake(endX, endY, box.frame.size.width, box.frame.size.height); 
       } 
       completion:nil]; 
+1

मेरी समस्या देरी एनीमेशन प्रति से नहीं है। यह काम करता है। मेरी समस्या यह है कि एनिमेटेड होने से पहले 3 सेकंड के दौरान एनिमेटेड (ले जाया गया और फीका हुआ) परत दिखाई देती है। – Armand

+1

हाँ। जैसा कि आपने रॉब कहा था। यह "3 सेकंड के लिए दृश्यमान शुरू होता है, और फिर गायब हो जाता है और धीरे-धीरे वापस आ जाता है और अगले सेकंड में एनिमेट करता है"। मैंने पोस्ट किए गए ब्लॉक से पहले परत बनाई है। मुझे लगा कि यह सबकुछ पोस्ट करने में बहुत लंबा रहा होगा। ऐसा लगता है कि मैं पहले सेकंड के लिए प्रदर्शित होने पर परत एनीमेशन में देरी कर सकता हूं या जब कोई एनीमेशन नहीं होता है तो मैं परत के प्रदर्शन में देरी कर सकता हूं। मजेदार। मैं setBeginTime और अवधि जैसी विधियों का उपयोग कर रहा हूं। ऑटोलायआउट या एनिमेट नहीं किया गया अवधि। कोई उपाय? – Armand

+0

@ user1915931 जबकि मुझे लगता है कि विचारों के ब्लॉक आधारित एनीमेशन का उपयोग करना बहुत आसान है, मैंने परतों को एनिमेट करने पर आपका दिल सेट करने पर भी 'CABasicAnimation' उत्तर' के साथ अपना जवाब अपडेट कर दिया है। – Rob

0

यह लेख अच्छी तरह से बताता है कि क्यों आप fillMode https://www.objc.io/issues/12-animations/animations-explained/

साथ removedOnCompletion उपयोग नहीं करना चाहिए मेरे मामले में मैं कर रहा हूँ एनिमेट एक दृश्य की परत जो नेविगेशन के रूप में कार्य करती है लेकिन उस दृश्य के अंदर एक बाउंस एनीमेशन देरी होती है; मुझे लेयर पर अपडेट की गई इन दोनों स्थितियों की आवश्यकता है क्योंकि इसे खारिज कर दिया जा सकता है और फिर फिर दिखाया जा सकता है। removedOnCompletion का उपयोग परत के मूल्य एक बार एनीमेशन

तरह से मैं क्या यह एक CATransaction पूरा होने के ब्लॉक

CATransaction.setCompletionBlock { 
    // update the layer value 
} 

CATransaction.begin() 

// setup and add your animation 

CATransaction.commit() 
0

में परत को अद्यतन beginTime का उपयोग कर आप अपने एनीमेशन वस्तु की आवश्यक विन्यास बनाना चाहिए के लिए है पूरा करता अपडेट नहीं करेंगे और

:

zoomAnimation.fillMode = kCAFillModeBackwards; 

एप्पल दस्तावेज में कहा है कि जैसे kCAFillModeBackwards को fillMode सेट

एनीमेशन के प्रारंभ समय को सेट करने के लिए स्टार्टटाइम प्रॉपर्टी का उपयोग करें। आम तौर पर, एनिमेशन अगले अपडेट चक्र के दौरान शुरू होते हैं। एनीमेशन स्टार्ट टाइम को कई सेकंड तक देरी करने के लिए आप स्टार्टटाइम पैरामीटर का उपयोग कर सकते हैं। एक साथ दो एनिमेशन को श्रृंखलाबद्ध करने का तरीका अन्य एनीमेशन के अंत समय से मेल खाने के लिए एक एनीमेशन के प्रारंभ समय को सेट करना है। यदि आप किसी एनीमेशन की शुरुआत में देरी करते हैं, तो आप fillMode प्रॉपर्टी को केसीएफ़िलमोडबैकवर्ड पर भी सेट करना चाहेंगे। यह भरने का तरीका परत को एनीमेशन के प्रारंभ मूल्य को प्रदर्शित करने का कारण बनता है, भले ही परत पेड़ में परत ऑब्जेक्ट में एक अलग मान हो। इस भरने मोड के बिना, एनीमेशन शुरू होने से पहले आपको अंतिम मूल्य पर कूद दिखाई देगी। अन्य भरने के तरीके भी उपलब्ध हैं।

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/AdvancedAnimationTricks/AdvancedAnimationTricks.html#//apple_ref/doc/uid/TP40004514-CH8-SW2

इसके अलावा, रोब के सवाल से:

अपने दो एनिमेशन के लिए, आप (kCAFillModeForwards को कोई और fillMode को removedOnCompletion बदलने के लिए यह सही तरीका यह पूर्ववत करने से रोकने के लिए है पूरा होने पर मूल स्थिति पर वापस)।

एक बार एनीमेशन निकाल दिया जाता है, प्रस्तुति परत मॉडल परत के मूल्यों करना प्रारंभ कर देगा, और उस परत के बाद से हम कभी नहीं संशोधित किया:

यह क्योंकि, विवादास्पद बयान का एक प्रकार है स्थिति, हमारी स्पेसशिप ठीक से फिर से दिखाई देती है जहां यह शुरू हुआ। इस समस्या से निपटने के दो तरीके हैं:

पहला तरीका सीधे मॉडल परत पर संपत्ति को अपडेट करना है। यह अनुशंसित दृष्टिकोण है, क्योंकि यह एनीमेशन को पूरी तरह से वैकल्पिक बनाता है।

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

https://www.objc.io/issues/12-animations/animations-explained/ से