Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

iphone - Inner Shadow in UILabel

is it possible to create such a UILabel with inner and outer shadow?

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

i only know shadowColor and shadowOffset

zoomed:

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

thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer by dmaclach is only suitable for shapes that can easily be inverted. My solution is a custom view that works with any shape and also text. It requires iOS 4 and is resolution independent.

First, a graphical explanation of what the code does. The shape here is a circle. alt text

The code draws text with a white dropshadow. If it's not required, the code could be refactored further, because the dropshadow needs to be masked differently. If you need it on an older version of iOS, you would have to replace the block and use an (annoying) 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];
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...