2010-11-25 25 views
12

मेरे पास दो मंडल हैं जो स्क्रीन के चारों ओर घूमती हैं। मंडलियां UIViews दोनों हैं जिनमें अन्य UIViews हैं। प्रत्येक सर्कल के बाहर का क्षेत्र पारदर्शी है।कोर एनीमेशन एनीमेशन ट्रैकिंग

मैंने एक CGPath बनाने के लिए एक फ़ंक्शन लिखा है जो दो मंडलियों को चतुर्भुज आकार से जोड़ता है। मैं इस पथ को पारदर्शी कैलियर में भरता हूं जो पूरी स्क्रीन को फैलाता है। चूंकि परत दो परिपत्र UIViews के पीछे है, इसलिए यह उन्हें कनेक्ट करने लगती है।

अंत में, दो UIViews कोर एनीमेशन का उपयोग करके एनिमेटेड हैं। इस एनीमेशन के दौरान स्थिति और आकार दोनों मंडलियों में परिवर्तन होता है।

अब तक केवल विधि है कि मैं के साथ किसी भी सफलता मिली है एक NSTimer का उपयोग कर नियमित अंतराल पर एनीमेशन बाधा डालते हैं, तो recompute और चक्र के presentationLayer के स्थान पर आधारित किरण आकर्षित करने के लिए है। हालांकि, चतुर्भुज एनीमेशन गति के दौरान सर्कल के पीछे है।

क्या कोर एनीमेशन का उपयोग करके इसे पूरा करने का एक बेहतर तरीका है? या मुझे कोर एनीमेशन से बचने और एनएसटीमर का उपयोग करके अपनी खुद की एनीमेशन लागू करनी चाहिए?

उत्तर

12

मुझे एक जैसी समस्या का सामना करना पड़ा। मैंने एनीमेशन के विचारों के बजाय परतों का उपयोग किया। आप इस तरह कुछ कोशिश कर सकते हैं।

  1. एक CALayer के रूप में प्रत्येक तत्व ड्रा और उन्हें अपने कंटेनर UIView की परत के लिए sublayers के रूप में शामिल हैं। UIViews एनिमेट करना आसान है, लेकिन आपके पास कम नियंत्रण होगा। ध्यान दें कि किसी भी दृश्य के लिए आप [परत परत] के साथ इसकी परत प्राप्त कर सकते हैं;
  2. अपने चतुर्भुज के लिए एक कस्टम sublayer बनाएँ। इस परत में एक संपत्ति या कई गुण हो सकते हैं जिन्हें आप इस परत के लिए एनिमेट करना चाहते हैं। चलो इस संपत्ति को "customprop" कहते हैं। क्योंकि यह एक कस्टम परत है, आप एनीमेशन के प्रत्येक फ्रेम पर फिर से लेना चाहते हैं। उन संपत्तियों के लिए जिन्हें आप एनिमेट करने की योजना बना रहे हैं, आपकी कस्टम लेयर क्लास को YES की ज़रूरतें वापस करनी चाहिए DisplayForKey:। इस तरह आप सुनिश्चित करें - (शून्य) drawInContext: (CGContextRef) theContext प्रत्येक फ्रेम पर कॉल किया जाता है।
  3. एक ही लेनदेन में सभी एनिमेशन (दोनों मंडल और चौकोर) रखें;

हलकों आप शायद CALayers का उपयोग करें और सामग्री अगर यह एक छवि है, मानक तरीका निर्धारित करते हैं, कर सकते हैं के लिए:

layer.contents = [UIImage imageNamed:@"circle_image.png"].CGImage; 

अब ट्रैक्टर परत के लिए,, उपवर्ग CALayer और लागू इस तरह से:

:

- (void)drawInContext:(CGContextRef)theContext{ 
    //Custom draw code here 
} 
+ (BOOL)needsDisplayForKey:(NSString *)key{ 
    if ([key isEqualToString:@"customprop"]) 
     return YES; 
    return [super needsDisplayForKey:key]; 
} 

लेन-देन की तरह लग रहे हैं

[CATransaction begin]; 
CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"customprop"]; 

theAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1000, 1000)]; 
theAnimation.duration=1.0; 
theAnimation.repeatCount=4; 
theAnimation.autoreverses=YES; 
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
theAnimation.delegate = self; 
[lay addAnimation:theAnimation forKey:@"selecting"]; 

[CATransaction setValue:[NSNumber numberWithFloat:10.0f] 
        forKey:kCATransactionAnimationDuration]; 
circ1.position=CGPointMake(1000, 1000); 
circ2.position=CGPointMake(1000, 1000); 
[CATransaction commit]; 

अब सभी ड्रा रूटीन एक ही समय में होंगे। सुनिश्चित करें कि आपका drawInContext: कार्यान्वयन तेज़ है। अन्यथा एनीमेशन अंतराल होगा।

UIViews की परत में प्रत्येक sublayer जोड़ने के बाद, [परत सेटNeedsDisplay] कॉल करने के लिए याद रखें। यह स्वचालित रूप से नहीं बुलाया जाता है।

मुझे पता है कि यह थोड़ा जटिल है। हालांकि, परिणामी एनिमेशन एनएसटीमर का उपयोग करने और प्रत्येक कॉल पर फिर से निकालने से बेहतर होते हैं।

+0

कस्टम गुणों का उपयोग करने के बजाय पूरी तरह से प्रोग्रामेटिक एनीमेशन को लागू करने का विकल्प चुनने वालों के लिए बस एक नोट: इसके लिए 'NSTimer' का उपयोग न करें; यह धीमा और सीपीयू-लालची होगा। एनीमेशन से संबंधित किसी भी चीज़ के लिए, ['CADisplayLink'] का उपयोग करें (https://developer.apple.com/library/ios/documentation/QuartzCore/Reference/CADisplayLink_ClassRef/), जो स्क्रीन रीफ्रेश दर के साथ सिंक्रनाइज़ किया गया है और कोरएनीमेशन द्वारा आंतरिक रूप से उपयोग किया जाता है । – skozin

1

यदि आपको परतों की वर्तमान दृश्य स्थिति को खोजने की आवश्यकता है, तो आप प्रश्न में कैलियर पर -presentationLayer पर कॉल कर सकते हैं, और यह आपको एक परत देगा जो प्रतिपादन के लिए उपयोग किए जाने वाले अनुमान को अनुमानित करता है। नोट मैंने अनुमान लगाया - यह पूरी तरह से सटीक होने की गारंटी नहीं है। हालांकि यह आपके उद्देश्यों के लिए पर्याप्त हो सकता है।

+0

जैसा कि मैंने उल्लेख किया है, मैंने पहले ही प्रेजेंटेशन लेयर का उपयोग करने का प्रयास किया है लेकिन यह मंडलियों के पीछे है। मुझे कई घटकों के एनीमेशन को सिंक्रनाइज़ करने की एक और अधिक विश्वसनीय विधि की आवश्यकता है। – titaniumdecoy

+0

एनीमेशन मशीनरी में बांधना एकमात्र विश्वसनीय तरीका है जिसे मैं सोच सकता हूं। आप CAShapeLayer का उपयोग करके और मंडलियों के साथ सिंक में अपना पथ एनिमेट कर सकते हैं। –

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