2010-07-12 15 views
17

में आंतरिक छाया क्या आंतरिक और बाहरी छाया के साथ ऐसा UILabel बनाना संभव है?UILabel

alt text http://dl.getdropbox.com/u/80699/Bildschirmfoto%202010-07-12%20um%2021.28.57.png

मैं केवल पता shadowColor और shadowOffset

जूम:

alt text http://dl.getdropbox.com/u/80699/Bildschirmfoto%202010-07-12%20um%2021.39.56.png

धन्यवाद!

+0

मैं कुछ समय पहले यूआईटीएक्स्टफिल्ड को अनुकरण करने के लिए यह जानना चाहता था और क्वार्ट्ज (सुझाए गए अनुसार) का उपयोग कर रहा था लेकिन कुछ प्रदर्शन समस्याएं हैं, मुझे पूरा यकीन है कि आपके UILabel प्रतिपादन की सीमाओं को एनिमेट करना अच्छा नहीं लगेगा यह सुस्त दिखता है। मेरे मामले में मैंने एक विस्तारित यूआईएममेज का उपयोग करके समाप्त किया: खिंचाव इमेज विथलिफ्ट कैपविड्थ: टॉप कैपहाइट: यदि आपकी आवश्यकताओं के अनुरूप यह बहुत तेज है – nacho4d

+3

आपके प्रश्न में छवि लिंक टूटे हुए हैं – jjxtra

उत्तर

125

dmaclach द्वारा जवाब आकृतियों है कि आसानी से उलटा किया जा सकता है के लिए ही उपयुक्त है। मेरा समाधान एक कस्टम दृश्य है जो किसी भी आकार और पाठ के साथ काम करता है। इसके लिए आईओएस 4 की आवश्यकता है और संकल्प स्वतंत्र है।

सबसे पहले, कोड के बारे में एक ग्राफिकल स्पष्टीकरण। यहां आकार एक सर्कल है। alt text

कोड एक सफेद ड्रॉपशैडो के साथ पाठ खींचता है। यदि इसकी आवश्यकता नहीं है, तो कोड को फिर से प्रतिक्रिया दी जा सकती है, क्योंकि ड्रॉपशैडो को अलग-अलग मास्क किया जाना चाहिए। यदि आपको आईओएस के पुराने संस्करण पर इसकी आवश्यकता है, तो आपको ब्लॉक को प्रतिस्थापित करना होगा और एक (परेशान) CGBitmapContext का उपयोग करना होगा।

- (UIImage*)blackSquareOfSize:(CGSize)size { 
    UIGraphicsBeginImageContextWithOptions(size, NO, 0); 
    [[UIColor blackColor] setFill]; 
    CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height)); 
    UIImage *blackSquare = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return blackSquare; 
} 


- (CGImageRef)createMaskWithSize:(CGSize)size shape:(void (^)(void))block { 
    UIGraphicsBeginImageContextWithOptions(size, NO, 0); 
    block(); 
    CGImageRef shape = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; 
    UIGraphicsEndImageContext(); 
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(shape), 
             CGImageGetHeight(shape), 
             CGImageGetBitsPerComponent(shape), 
             CGImageGetBitsPerPixel(shape), 
             CGImageGetBytesPerRow(shape), 
             CGImageGetDataProvider(shape), NULL, false); 
    return mask; 
} 


- (void)drawRect:(CGRect)rect { 
    UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:40.0f]; 
    CGSize fontSize = [text_ sizeWithFont:font]; 

    CGImageRef mask = [self createMaskWithSize:rect.size shape:^{ 
    [[UIColor blackColor] setFill]; 
    CGContextFillRect(UIGraphicsGetCurrentContext(), rect); 
    [[UIColor whiteColor] setFill]; 
    // custom shape goes here 
    [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), 0) withFont:font]; 
    [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font]; 
    }]; 

    CGImageRef cutoutRef = CGImageCreateWithMask([self blackSquareOfSize:rect.size].CGImage, mask); 
    CGImageRelease(mask); 
    UIImage *cutout = [UIImage imageWithCGImage:cutoutRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp]; 
    CGImageRelease(cutoutRef); 

    CGImageRef shadedMask = [self createMaskWithSize:rect.size shape:^{ 
    [[UIColor whiteColor] setFill]; 
    CGContextFillRect(UIGraphicsGetCurrentContext(), rect); 
    CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, 1), 1.0f, [[UIColor colorWithWhite:0.0 alpha:0.5] CGColor]); 
    [cutout drawAtPoint:CGPointZero]; 
    }]; 

    // create negative image 
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0); 
    [[UIColor blackColor] setFill]; 
    // custom shape goes here 
    [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font]; 
    UIImage *negative = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    CGImageRef innerShadowRef = CGImageCreateWithMask(negative.CGImage, shadedMask); 
    CGImageRelease(shadedMask); 
    UIImage *innerShadow = [UIImage imageWithCGImage:innerShadowRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp]; 
    CGImageRelease(innerShadowRef); 

    // draw actual image 
    [[UIColor whiteColor] setFill]; 
    [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -0.5) withFont:font]; 
    [[UIColor colorWithWhite:0.76 alpha:1.0] setFill]; 
    [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font]; 

    // finally apply shadow 
    [innerShadow drawAtPoint:CGPointZero]; 
} 
+0

वाह, यह वास्तव में सहायक था! पता नहीं क्यों शून्य वोट थे ... दुर्भाग्यवश, समाधान के लिए +1 से अधिक सेट नहीं कर सकते हैं। :) –

+6

मैंने गिटहब पर इस दृष्टिकोण का उपयोग करने के लिए कुछ फ़ंक्शंस भी बनाए हैं: https://github.com/mruegenberg/objc-utils/tree/master/UIKitAdditions। InnerShadowDrawing.h/.m फ़ाइलों को देखें। – mrueg

+0

उत्कृष्ट सामग्री –

0

आपको आंतरिक छाया प्राप्त करने के लिए अपना स्वयं का कस्टम ड्राइंग करना होगा। मानक UILabel के साथ वर्तमान में ऐसा करने का कोई तरीका नहीं है।

क्वार्ट्ज के साथ आंतरिक छाया करने पर एक उचित स्पष्टीकरण दिया गया है।

Inner shadow in Core Graphics

13

हालांकि स्टीव जवाब काम करता है, यह मेरी विशेष मामले के पैमाने पर नहीं था और इसलिए मैं अपने संदर्भ कतरन के बाद एक CGPath को एक छाया लगाने से एक आंतरिक छाया बना दी:

CGContextRef context = UIGraphicsGetCurrentContext(); 

// clip context so shadow only shows on the inside 
CGPathRef roundedRect = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:4].CGPath; 
CGContextAddPath(context, roundedRect); 
CGContextClip(context); 

CGContextAddPath(context, roundedRect); 
CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, 0), 3, [UIColor colorWithWhite:0 alpha:1].CGColor); 
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:0 alpha:1].CGColor); 
CGContextStrokePath(context); 

जिसमें परिणाम:

enter image description here

आप छाया ऑफसेट बदल सकते हैं और छाया शैली बदलने के लिए धुंधला कर सकते हैं। यदि आपको इसे गहरा होने की आवश्यकता है, तो आप लगातार उसी सीजीपाथ को भी जोड़ सकते हैं और फिर छाया को ढेर कर सकते हैं।

+0

अरे सैम, यह बहुत अच्छा है और मेरे लिए अच्छा काम करता है, लेकिन क्या आप जानते हैं कि सीमा के बिना यह वही प्रभाव कैसे प्राप्त करें? या हो सकता है कि सिर्फ एक सीमा जो लगभग आधा अस्पष्टता है? –

7

मैं आंतरिक छाया के लिए FXLabel का उपयोग करता हूं, यहां देखें https://github.com/nicklockwood/FXLabel

+3

वाह अद्भुत गिट! यह स्टेरॉयड पर UILabel की तरह है! धन्यवाद! –

2

हां, मेरे पास इसके बारे में एक ब्लॉग पोस्ट है here

+ (Class)layerClass 
{ 
    return [JTAInnerShadowLayer class]; 
} 

फिर परत JTAInnerShadowLayer कुछ की स्थापना के लिए init विधि में: संक्षिप्त उत्तर here, उपवर्ग UILabel से JTAInnerShadowLayer उधार, और + (Class)layerClass अधिभावी द्वारा अपने layerclass बदलने के लिए इतना है कि यह इस तरह JTAInnerShadowLayer वर्ग रिटर्न है इस तरह:

[self setBackgroundColor:[UIColor clearColor]]; 
JTAInnerShadowLayer *innerShadow = (JTAInnerShadowLayer *)[self layer]; 
[innerShadow setClipForAnyAlpha:YES]; 
[innerShadow setOutsideShadowSize:CGSizeMake(0.0, 1.0) radius:1.0]; 
[innerShadow setInsideShadowSize:CGSizeMake (0.0, 4.0) radius:6.0]; 
/* Uncomment this to make the label also draw the text (won't work well 
    with black text!*/ 
//[innerShadow drawOriginalImage]; 

(या केवल JTAIndentLabel क्लास उधार लें)।

0

PaintCode परीक्षण संस्करण का प्रयास करें!शुरुआती लोगों के लिए, आप कस्टम चित्र बनाने के तरीके सीखेंगे। यह बहुत अच्छा है! : 3 आप इसे अभ्यास के लिए या सीखने के लिए उपयोग कर सकते हैं, लेकिन हर समय इसका उपयोग न करें, आपको यह भी सीखना चाहिए कि अपने आप को चित्र कैसे बनाएं।

अस्वीकरण: मैं एक समर्थक नहीं हूं, मैं अपनी खोज से आश्चर्यचकित था। ;)