我有以下CALayer:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake(8, 57, 296, 30);
gradient.cornerRadius = 3.0f;
gradient.colors = [NSArray arrayWithObjects:(id)[RGB(130, 0, 140) CGColor], (id)[RGB(108, 0, 120) CGColor], nil];
[self.layer insertSublayer:gradient atIndex:0];
我想添加一个内部阴影效果,但我不太确定如何做到这一点。我想我会被要求在drawRect中绘制,但是这会在其他UIView对象上添加图层,因为它应该是一些按钮后面的一个栏,所以我不知所措?
我可以添加另一个层,但同样,不确定如何实现内部阴影效果(如下所示:
感谢你的帮助。
发布于 2011-04-05 01:30:48
对于任何其他想知道如何按照Costique的建议使用核心图形绘制内部阴影的人,那么这是如何:(在iOS上根据需要调整)
在您的drawRect:方法中...
CGRect bounds = [self bounds];
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat radius = 0.5f * CGRectGetHeight(bounds);
// Create the "visible" path, which will be the shape that gets the inner shadow
// In this case it's just a rounded rect, but could be as complex as your want
CGMutablePathRef visiblePath = CGPathCreateMutable();
CGRect innerRect = CGRectInset(bounds, radius, radius);
CGPathMoveToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y);
CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x + innerRect.size.width, bounds.origin.y);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y, bounds.origin.x + bounds.size.width, innerRect.origin.y, radius);
CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, innerRect.origin.y + innerRect.size.height);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, innerRect.origin.x + innerRect.size.width, bounds.origin.y + bounds.size.height, radius);
CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y + bounds.size.height);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x, bounds.origin.y + bounds.size.height, bounds.origin.x, innerRect.origin.y + innerRect.size.height, radius);
CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x, innerRect.origin.y);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x, bounds.origin.y, innerRect.origin.x, bounds.origin.y, radius);
CGPathCloseSubpath(visiblePath);
// Fill this path
UIColor *aColor = [UIColor redColor];
[aColor setFill];
CGContextAddPath(context, visiblePath);
CGContextFillPath(context);
// Now create a larger rectangle, which we're going to subtract the visible path from
// and apply a shadow
CGMutablePathRef path = CGPathCreateMutable();
//(when drawing the shadow for a path whichs bounding box is not known pass "CGPathGetPathBoundingBox(visiblePath)" instead of "bounds" in the following line:)
//-42 cuould just be any offset > 0
CGPathAddRect(path, NULL, CGRectInset(bounds, -42, -42));
// Add the visible path (so that it gets subtracted for the shadow)
CGPathAddPath(path, NULL, visiblePath);
CGPathCloseSubpath(path);
// Add the visible paths as the clipping path to the context
CGContextAddPath(context, visiblePath);
CGContextClip(context);
// Now setup the shadow properties on the context
aColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.5f];
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 3.0f, [aColor CGColor]);
// Now fill the rectangle, so the shadow gets drawn
[aColor setFill];
CGContextSaveGState(context);
CGContextAddPath(context, path);
CGContextEOFillPath(context);
// Release the paths
CGPathRelease(path);
CGPathRelease(visiblePath);
因此,本质上有以下步骤:
发布于 2012-07-11 23:55:19
我知道我来晚了,但这会帮助我在旅途中发现...
值得肯定的是,这本质上是Daniel Thorpe对Costique从较大区域中减去较小区域的解决方案的阐述的修改。此版本适用于使用图层组合而不是覆盖-drawRect:
的用户
CAShapeLayer
类可用于实现相同的效果:
CAShapeLayer *shadowLayer = [CAShapeLayer layer];
[shadowLayer setFrame:[self bounds]];
// Standard shadow stuff
[shadowLayer setShadowColor:[[UIColor colorWithWhite:0 alpha:1] CGColor]];
[shadowLayer setShadowOffset:CGSizeMake(0.0f, 0.0f)];
[shadowLayer setShadowOpacity:1.0f];
[shadowLayer setShadowRadius:5];
// Causes the inner region in this example to NOT be filled.
[shadowLayer setFillRule:kCAFillRuleEvenOdd];
// Create the larger rectangle path.
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectInset(bounds, -42, -42));
// Add the inner path so it's subtracted from the outer path.
// someInnerPath could be a simple bounds rect, or maybe
// a rounded one for some extra fanciness.
CGPathAddPath(path, NULL, someInnerPath);
CGPathCloseSubpath(path);
[shadowLayer setPath:path];
CGPathRelease(path);
[[self layer] addSublayer:shadowLayer];
在这一点上,如果您的父层没有遮罩到其边界,您将看到遮罩层的额外区域周围的层的边缘。如果你只是直接复制这个例子,这将是42个像素的黑色。要摆脱它,你可以简单地使用另一个具有相同路径的CAShapeLayer
,并将其设置为阴影层的蒙版:
CAShapeLayer *maskLayer = [CAShapeLayer layer];
[maskLayer setPath:someInnerPath];
[shadowLayer setMask:maskLayer];
我自己没有对此进行基准测试,但我怀疑将此方法与光栅化结合使用会比覆盖-drawRect:
更有效。
发布于 2010-12-14 01:23:39
可以使用Core Graphics绘制内部阴影,方法是在边界外创建一个大的矩形路径,减去边界大小的矩形路径,并在生成的路径上填充“正常”阴影。
但是,由于您需要将其与渐变层相结合,我认为一个更简单的解决方案是创建一个内部阴影的9部分透明PNG图像,并将其拉伸到合适的大小。由9部分组成的阴影图像将如下所示(其大小为21x21像素):
CALayer *innerShadowLayer = [CALayer layer];
innerShadowLayer.contents = (id)[UIImage imageNamed: @"innershadow.png"].CGImage;
innerShadowLayer.contentsCenter = CGRectMake(10.0f/21.0f, 10.0f/21.0f, 1.0f/21.0f, 1.0f/21.0f);
然后设置innerShadowLayer的帧,它应该正确地拉伸阴影。
https://stackoverflow.com/questions/4431292
复制相似问题