2012-10-09 45 views
6

मैं एक साधारण ऐप बना रहा हूं जहां उपयोगकर्ता बटन दबाएगा, स्क्रीन पर लाइनों की एक श्रृंखला खींची जाएगी और उपयोगकर्ता वास्तविक समय में खींचे गए इन लाइनों को देख पाएंगे (लगभग एनीमेशन की तरह) ।ड्राइंग एनीमेशन

1) जैसे ही उपयोगकर्ता बटन दबाता है के रूप में, UIThread ब्लॉक ड्राइंग है जब तक:

UIGraphicsBeginImageContext(CGSizeMake(300,300)); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

for (int i = 0; i < 100; i++) { 
    CGContextMoveToPoint(context, i, i); 
    CGContextAddLineToPoint(context, i+20, i+20); 
    CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]); 
    CGContextStrokePath(context); 
} 

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

UIGraphicsEndImageContext(); 

मेरे समस्या यह है कि यह है:

मेरे कोड कुछ इस तरह (सरलीकृत किया गया है) लग रहा है किया हुआ।

2) मुझे स्क्रीन पर एक बार स्क्रीन पर खींचना नहीं जा सकता है - मैंने यूआईएममेज को लूप के अंदर सीधे सेट करने की कोशिश की है और लूप के अंदर परत सामग्री सेट करने का भी प्रयास किया है।

मैं इन समस्याओं के आसपास कैसे हो सकता हूं?

+0

क्या इससे मदद मिलती है? http://stackoverflow.com/questions/9245954/moving-an-image-along-a-series-of-cgpoints –

+0

आप किस तरह की देरी चाहते हैं? – nielsbot

+0

एक अनुकूलन देरी अच्छी होगी - मुझे लगता है कि रॉब के पास जो मैं ढूंढ रहा था ... आपकी मदद के लिए धन्यवाद! – HHHH

उत्तर

16

आप कहते हैं "बस एक एनीमेशन की तरह"। एक वास्तविक एनीमेशन क्यों नहीं, एक ला कोर ग्राफिक्स 'CABasicAnimation? क्या आपको वाकई इसे लाइनों की श्रृंखला के रूप में दिखाने की ज़रूरत है, या एक उचित एनीमेशन ठीक है?

आप लाइन की वास्तविक ड्राइंग चेतन करना चाहते हैं, तो आप की तरह कुछ कर सकता है:

#import <QuartzCore/QuartzCore.h> 

- (void)drawBezierAnimate:(BOOL)animate 
{ 
    UIBezierPath *bezierPath = [self bezierPath]; 

    CAShapeLayer *bezier = [[CAShapeLayer alloc] init]; 

    bezier.path   = bezierPath.CGPath; 
    bezier.strokeColor = [UIColor blueColor].CGColor; 
    bezier.fillColor  = [UIColor clearColor].CGColor; 
    bezier.lineWidth  = 5.0; 
    bezier.strokeStart = 0.0; 
    bezier.strokeEnd  = 1.0; 
    [self.view.layer addSublayer:bezier]; 

    if (animate) 
    { 
     CABasicAnimation *animateStrokeEnd = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
     animateStrokeEnd.duration = 10.0; 
     animateStrokeEnd.fromValue = [NSNumber numberWithFloat:0.0f]; 
     animateStrokeEnd.toValue = [NSNumber numberWithFloat:1.0f]; 
     [bezier addAnimation:animateStrokeEnd forKey:@"strokeEndAnimation"]; 
    } 
} 

फिर तुम सब करने की है बनाने है अपनी लाइन के लिए UIBezierPath, जैसे:

- (UIBezierPath *)bezierPath 
{ 
    UIBezierPath *path = [UIBezierPath bezierPath]; 

    [path moveToPoint:CGPointMake(0.0, 0.0)]; 

    [path addLineToPoint:CGPointMake(200.0, 200.0)]; 

    return path; 
} 

यदि आप चाहते हैं, तो आप एक ही पथ में एक साथ लाइनों का एक गुच्छा पैच कर सकते हैं, उदाहरण के लिए यहां लाइनों की मोटे तौर पर साइन वक्र आकार की श्रृंखला है:

- (UIBezierPath *)bezierPath 
{ 
    UIBezierPath *path = [UIBezierPath bezierPath]; 
    CGPoint point = self.view.center; 

    [path moveToPoint:CGPointMake(0, self.view.frame.size.height/2.0)]; 

    for (CGFloat f = 0.0; f < M_PI * 2; f += 0.75) 
    { 
     point = CGPointMake(f/(M_PI * 2) * self.view.frame.size.width, sinf(f) * 200.0 + self.view.frame.size.height/2.0); 
     [path addLineToPoint:point]; 
    } 

    return path; 
} 

और ये मुख्य धागे को अवरुद्ध नहीं करते हैं।

वैसे, आप स्पष्ट रूप से करने के लिए CoreGraphics.framework जोड़ना होगा अपने लक्ष्य के Build SettingsLink Binary With Libraries के तहत।

+1

यह बढ़िया है - धन्यवाद! बस एक और सवाल - मैं [पथ addLineToPoint] कई बार कॉल कर रहा हूं (शायद 1000+)। आपके विधि को लागू करने के बाद, मुझे लगता है कि मेरा एप्लिकेशन और डिवाइस जिस पर चल रहा है वह बेहद धीमा/झटकेदार हो जाता है। मैंने एप्लिकेशन को प्रोफाइल किया है और ऐसा लगता है कि सीपीयू की एक बड़ी मात्रा का उपयोग नहीं किया जा रहा है - क्या आपको पता है कि यह क्यों होगा? – HHHH

+0

@HHHH मैं आसानी से कल्पना कर सकता हूं कि यह डिवाइस पर कर लगाएगा। एक बार जब आप अधिक से अधिक शुरू करते हैं, तो कहें, प्रति सेकंड 30 लाइन सेगमेंट, एप के साथ एनीमेशन के साथ रहना कठिन होगा। मुझे नहीं पता कि कट ऑफ कहां है (क्या यह 30/सेकेंड है? 60? 100? मुझे नहीं पता), लेकिन किसी बिंदु पर, किसी दिए गए फ्रेम के लिए पथ खींचने के लिए कितना समय लगता है एनीमेशन, अब प्रत्येक फ्रेम ले जाएगा। और एक बार जब एनीमेशन प्रति सेकंड 30 फ्रेम से कम हो जाता है, तो यह अधिक झटकेदार होगा। आपको किसी भी तरह से लाइन सेगमेंट की संख्या पर कटौती करना होगा जिसे प्रति सेकेंड खींचा जाना चाहिए। आह। – Rob

+1

@HHHH शायद आप एनीमेशन की अवधि _x/y_ होने के लिए सेट कर सकते हैं जहां _x_ लाइन सेगमेंट की संख्या है और _y_ प्रति सेकेंड सेगमेंट की संख्या है जिसे आप समर्थन देंगे (एक ऐसा आंकड़ा जिसे आप शायद प्रयोग करना चाहते हैं , यह पता लगाने के लिए कि आप बिना किसी झटके से दूर हो सकते हैं, शायद 30 या 60 या 100 या ...)। – Rob