2012-10-14 27 views
15

के साथ एक बहुत ही पतली रेखा खींचना मैं अपने UIView की drawRect विधि में एक रेखा की एक बहुत पतली हेयरलाइन चौड़ाई खींचना चाहता हूं। जिस पंक्ति में मैं देखता हूं उसके पास CGContextSetLineWidth के लिए मान 0.5 है, वह एक समान 1.0 चौड़ाई मान से मेल नहीं खाता है जिसका उपयोग सीमा CALAYER को आकर्षित करने के लिए किया जाता है।CGContextAddLineToPoint और CGContextSetLineWidth

आप दोनों के बीच का अंतर देख सकते हैं - लाल रेखा (चौड़ाई = 1) बैंगनी/नीली रेखा (चौड़ाई = 0.5) से बहुत पतली है।

Border drawn with CALayer

यहाँ कैसे मैं अपने छद्म 1.0 चौड़ाई क्षैतिज रेखा खींचने रहा है:

UIView *myView = (UIView *)self; 
CALayer *layer = myView.layer; 
layer.borderColor = [UIColor redColor].CGColor; 
layer.borderWidth = 1.0; 

:

CGContextRef ctx = UIGraphicsGetCurrentContext(); 
CGContextSetStrokeColorWithColor(ctx, [UIColor blueColor].CGColor); 
CGContextSetLineWidth(ctx, 0.5); // I expected a very thin line 

CGContextMoveToPoint(ctx, 0, y); 
CGContextAddLineToPoint(ctx, self.bounds.size.width, y); 

CGContextStrokePath(ctx); 

यहाँ एक ही दृश्य के लिए एक बॉर्डर है, इस समय 1.0 बॉर्डर चौड़ाई का उपयोग कर मुझे अपनी खुद की कस्टम लाइन को आकर्षित करने के लिए अलग-अलग करने की क्या ज़रूरत है जो कैलियर संस्करण की समान चौड़ाई है?

उत्तर

38

जब आप पथ को स्ट्रोक करते हैं, स्ट्रोक पथ को पथबद्ध करता है। इसे एक और तरीका कहने के लिए, पथ स्ट्रोक के केंद्र के साथ स्थित है।

यदि पथ दो पिक्सल के बीच किनारे के साथ चलता है, तो स्ट्रोक (आंशिक रूप से) उस किनारे के दोनों किनारों पर पिक्सेल को कवर करेगा। 0.5 की रेखा चौड़ाई के साथ, एक क्षैतिज स्ट्रोक मार्ग के ऊपर पिक्सेल में 0.25 अंक बढ़ाएगा, और 0.25 अंक पथ के नीचे पिक्सेल में होगा।

आप तो यह पिक्सल के किनारे के साथ नहीं चलता है अपने पथ बढ़ने की जरूरत है:

CGFloat lineWidth = 0.5f; 
CGContextSetLineWidth(ctx, lineWidth); 

// Move the path down by half of the line width so it doesn't straddle pixels. 
CGContextMoveToPoint(ctx, 0, y + lineWidth * 0.5f); 
CGContextAddLineToPoint(ctx, self.bounds.size.width, y + lineWidth * 0.5f); 

लेकिन जब से तुम सिर्फ एक क्षैतिज रेखा ड्राइंग कर रहे हैं, इसका इस्तेमाल करना अधिक आसान है CGContextFillRect:

CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor); 
CGContextFillRect(ctx, CGRectMake(0, y, self.bounds.size.width, 0.5f)); 
+0

यह एक तरह का जादू है! यह काम करता है, लेकिन क्या आप समझा सकते हैं कि मुझे लाइन चौड़ाई के रास्ते से नीचे क्यों जाना चाहिए या कुछ लिंक देना चाहिए? – PSsam

+6

http://stackoverflow.com/a/13674460/77567 –

+0

लेकिन उन्होंने टेक्स्ट की 6 स्पष्ट पंक्तियों में इतनी स्पष्ट रूप से समझाया ... पतली रेखाओं को चित्रित करते समय पिक्सेल सीमाओं को झुकाव से बचें। ड्राइंग तंत्र का एंटीअलाइजिंग "smeared" लाइन बनाता है जो आपको अपेक्षा की तुलना में मोटा दिखता है, लेकिन वे नहीं हैं। –

16

अभिन्न अंग पर खींचे जाने पर आपको पतली रेखा प्राप्त करने के लिए एंटीअलाइजिंग बंद करने की आवश्यकता है।

CGContextSetShouldAntialias(ctx, NO) 
+0

यह मेरा दिन बना दिया :-) – Bartserk

+0

मदद की खुशी है, मैंने अक्सर एंटीअलियास को अनदेखा कर दिया है। – Conor

+0

मैं इसे आईओएस 7 ऐप पर रेट कर रहा था, रेटिना में 1 पिक्सेल लाइन, इस कमांड पर कोई प्रभाव नहीं पड़ा। YMMV। –