2012-05-19 9 views
11

iOS पर, हमआईओएस पर, UIBezierPath ड्राइंग को संदर्भ की आवश्यकता क्यों नहीं है?

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextBeginPath (context); 
CGContextMoveToPoint(context, 0, 0); 
CGContextAddLineToPoint(context, 100, 100); 
CGContextStrokePath(context); 

का उपयोग कर drawRect में एक रेखा खींच कर सकते हैं, लेकिन यदि हम उपरोक्त कोड को दूर हम भी एक आयत आकर्षित कर सकते हैं, और बस का उपयोग करें:

UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)]; 
[path stroke]; 

दो संबंधित प्रश्नों:

1) UIBezierPath को वर्तमान संदर्भ प्राप्त करने या उपयोग करने की आवश्यकता क्यों नहीं है?

2) यदि मेरे पास दो संदर्भ हैं: स्क्रीन के लिए एक, और एक बिटमैप संदर्भ है, तो यह बताएं कि UIBezierPath के लिए कौन सा संदर्भ आकर्षित करना है? मैंने सोचा कि यह UIGraphicsSetCurrentContext हो सकता है लेकिन यह अस्तित्व में नहीं है।

उत्तर

22

UIBezierPath एक संदर्भ का उपयोग करता है। यह वर्तमान UIKit ग्राफिक्स संदर्भ का उपयोग करता है। यह वही बात है जो आप पहले से ही UIGraphicsGetCurrentContext() के साथ प्राप्त कर रहे हैं।

यदि आप UIBezierPath को एक अलग संदर्भ का उपयोग करने के लिए चाहते हैं तो आप UIGraphicsPushContext() का उपयोग कर सकते हैं, लेकिन आपको पूरा होने पर UIGraphicsPopContext() का उपयोग करना याद रखना होगा।

+1

तो हम प्रयोग करेंगे 'UIGraphicsPushContext (myBitmapContext);' एक बिटमैप संदर्भ में ड्राइंग शुरू करने के लिए? –

+2

@ 動靜 能量: यह सही है –

5

iOS पर, हम

का उपयोग कर रहा इस बयान के महत्वपूर्ण हिस्सा हाइलाइट किया था drawRect में एक पंक्ति आकर्षित कर सकते हैं। drawRect: के अंदर, UIKit द्वारा आपके लिए एक संदर्भ पहले ही स्थापित किया जा चुका है, और किसी ऑब्जेक्ट-आधारित ड्राइंग निर्देश सीधे उस संदर्भ में जाते हैं। UIBezierPath वास्तव में उस संदर्भ का उपयोग कर रहा है, इसे स्पष्ट रूप से पारित करने की आवश्यकता नहीं है।

कोको टच में, हमेशा एक चित्र संदर्भ होना चाहिए (इस मामले में, संदर्भ अंततः स्क्रीन पर चित्रित किया जाएगा)। यदि आप drawRect: के अंदर नहीं थे, तो आपको स्वयं एक संदर्भ बनाना होगा।

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextBeginPath (context); 
CGContextMoveToPoint(context, 0, 0); 

सूचना है कि पहले समारोह कॉल CurrentContext() जाओ है। जब आप कोरग्राफिक्स के कार्यात्मक ड्राइंग इंटरफ़ेस का उपयोग कर रहे हैं, तो आपको प्रत्येक फ़ंक्शन में एक संदर्भ पारित करने की आवश्यकता है, लेकिन आप यहां एक नहीं बना रहे हैं, आप बस उस व्यक्ति को पुनर्प्राप्त कर रहे हैं जो पहले से मौजूद है।

Graphics contexts एक ढेर में हैं। यदि आप अपने द्वारा बनाए गए संदर्भ में आकर्षित करना चाहते हैं, तो आप इसे UIGraphicsPushContext() (जैसा कि केविन पहले से ही उल्लेख किया गया है) का उपयोग करके स्टैक पर दबाएं, फिर पिछले एक को वापस पॉप करें।

6

मैंने सोचा कि यह उल्लेख करना उपयोगी हो सकता है कि CGContextFillRect एक UIBezierPath का उपयोग करने से ~ 8.5x तेज है जो मैं बता सकता हूं (यदि प्रदर्शन एक कारक है और यह मानते हुए कि आपको अधिक जटिल ड्राइंग के लिए UIBezierPath का उपयोग करने की आवश्यकता नहीं है)।

मैंने ऐप्पल के HazardMap उदाहरण (http://developer.apple.com/library/ios/#samplecode/HazardMap/Introduction/Intro.html) में कुछ समय जोड़ा और एमएस प्रति रेक्ट में समय ~ 0.00064 एमएस/UIBezierPath दृष्टिकोण के लिए CGContextFillRect दृष्टिकोण बनाम ~ 0.00543 एमएस/रेक्ट के लिए rect, संभवतः बी/सी बाद वाले को ओवरहेड पास करने के लिए अधिक संदेश की आवश्यकता होती है।

यानी।zoomScale: InContext मैं

CGContextFillRect(ctx, boundaryCGRect); 

का उपयोग कर HazardMapView में भीतरी पाश में

UIBezierPath* path = [UIBezierPath bezierPathWithRect:boundaryCGRect]; 
[path fill]; 

का उपयोग कर (प्लस उपर्युक्त धक्का/संदर्भ कि HazardMapView drawMapRect में भेजा जाता है पॉप में परिवर्तन बनाम तुलना कर रहा हूं :)।

ईटीए

+1

ध्यान दें कि उपर्युक्त संख्या मैकबुक प्रो (2012 की शुरुआत) पर चल रहे आईफोन 6.0 सिम्युलेटर से हैं। एक वास्तविक iPad3 CGContextFillRect पर इसे चलाने से UIBezierPath दृष्टिकोण का उपयोग करने से ~ 5.7x तेज लगता है। निश्चित रूप से वाईएमएमवी इस बात पर निर्भर करता है कि आप किस डिवाइस का उपयोग कर रहे हैं (ऑप्टिमाइज़ेशन सेटिंग्स इस पर बहुत अधिक प्रभाव नहीं लगती हैं)। – ETA

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