UIView图层上的内部阴影效果?

我有以下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对象的顶部添加该层,因为它应该是某些按钮后面的一个栏,所以我无所适从?


我可以添加另一层,但是同样,不确定如何实现内部阴影效果(如下所示:


http://img3.mukewang.com/5d96ff4b0001ec3402300094.jpg

帮助赞赏...


米脂
浏览 1266回答 3
3回答

绝地无双

对于任何其他想知道如何根据Costique建议使用Core Graphics绘制内部阴影的人,这就是如何:(在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 wantCGMutablePathRef 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 pathUIColor *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 shadowCGMutablePathRef 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 > 0CGPathAddRect(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 contextCGContextAddPath(context, visiblePath); CGContextClip(context);         // Now setup the shadow properties on the contextaColor = [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 pathsCGPathRelease(path);    CGPathRelease(visiblePath);因此,基本上有以下步骤:创建你的道路设置所需的填充颜色,将此路径添加到上下文中,然后填充上下文现在创建一个更大的矩形,可以绑定可见路径。在关闭此路径之前,请添加可见路径。然后关闭路径,以便创建一个形状,其中减去了可见路径。您可能要研究填充方法(偶数/奇数的非零缠绕),具体取决于创建这些路径的方式。本质上,要使子路径在将它们添加在一起时“减去”,您需要沿相反的方向(一个顺时针方向,另一个逆时针方向)绘制(或构造)它们。然后,您需要将可见路径设置为上下文上的剪切路径,以免在屏幕外绘制任何内容。然后在上下文上设置阴影,包括阴影,模糊和颜色。然后在大形状中填充孔。颜色无关紧要,因为如果您正确完成所有操作,就不会看到此颜色,而只会看到阴影。

拉风的咖菲猫

我知道我参加这个聚会迟到了,但这本可以帮助我在旅途中尽早找到...为了在信用到期的地方提供信用,这本质上是对丹尼尔·索普(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:。
打开App,查看更多内容
随时随地看视频慕课网APP