是否可以创建具有内部和外部阴影的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 :(得分:126)
dmaclach的答案仅适用于易于倒置的形状。我的解决方案是一个自定义视图,适用于任何形状和文本。它需要iOS 4并且与分辨率无关。
首先,对代码的作用进行图解说明。这里的形状是一个圆圈。
代码使用白色阴影绘制文本。如果不需要,可以进一步重构代码,因为需要以不同方式屏蔽阴影。如果您需要在较旧版本的iOS上使用它,则必须替换该块并使用(恼人的)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];
}
答案 1 :(得分: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);
结果是:
您可以更改阴影偏移和模糊以更改阴影样式。如果你需要它更暗,你也可以连续添加然后抚摸相同的CGPath,这将使阴影堆积起来。
答案 2 :(得分:7)
我使用FXLabel作为内部阴影,请看https://github.com/nicklockwood/FXLabel。
答案 3 :(得分:2)
是的,我有一篇关于它的博客文章here。简短的回答是从here子类UILabel借用JTAInnerShadowLayer,并通过覆盖+ (Class)layerClass
来更改其图层类,以便它返回JTAInnerShadowLayer类,如下所示:
+ (Class)layerClass
{
return [JTAInnerShadowLayer class];
}
然后在图层的init方法中设置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类)。
答案 4 :(得分:0)
答案 5 :(得分:0)
试用PaintCode试用版!对于初学者,您将学习如何创建自定义绘图。这是很不错的! :3您可以将它用于练习或学习,但不要一直使用它,您还应该学习如何自己创建绘图。
免责声明:我不是代言人,我对我的发现感到惊讶。 ;)