似乎您想要一个看起来像阴影的边框。由于阴影呈现出某种渐变,乍一看无法将边框设置为渐变。但是,可以创建一个表示边界的路径,然后用渐变填充它。Apple 提供了一个似乎鲜为人知的功能,称为CGPathCreateCopyByStrokingPath。这需要一条路径(例如,圆角矩形)并创建一个新路径,该路径将是旧路径的笔划,给定您传递给函数的设置(如线宽、连接/上限设置、斜接限制等)。因此,假设您定义了一条路径(这不完全是 Apple 提供的,但它是相似的):
+ (UIBezierPath *) bezierPathForBackButtonInRect:(CGRect)rect withRoundingRadius:(CGFloat)radius{
UIBezierPath *path = [UIBezierPath bezierPath];
CGPoint mPoint = CGPointMake(CGRectGetMaxX(rect) - radius, rect.origin.y);
CGPoint ctrlPoint = mPoint;
[path moveToPoint:mPoint];
ctrlPoint.y += radius;
mPoint.x += radius;
mPoint.y += radius;
if (radius > 0) [path addArcWithCenter:ctrlPoint radius:radius startAngle:M_PI + M_PI_2 endAngle:0 clockwise:YES];
mPoint.y = CGRectGetMaxY(rect) - radius;
[path addLineToPoint:mPoint];
ctrlPoint = mPoint;
mPoint.y += radius;
mPoint.x -= radius;
ctrlPoint.x -= radius;
if (radius > 0) [path addArcWithCenter:ctrlPoint radius:radius startAngle:0 endAngle:M_PI_2 clockwise:YES];
mPoint.x = rect.origin.x + (10.0f);
[path addLineToPoint:mPoint];
[path addLineToPoint:CGPointMake(rect.origin.x, CGRectGetMidY(rect))];
mPoint.y = rect.origin.y;
[path addLineToPoint:mPoint];
[path closePath];
return path;
}
这将返回类似于 Apple 的后退按钮的路径(我在我的应用程序中使用它)。我已将此方法(以及更多方法)作为一个类别添加到 UIBezierPath。
现在让我们在绘图例程中添加该内部阴影:
- (void) drawRect:(CGRect)rect{
UIBezierPath *path = [UIBezierPath bezierPathForBackButtonInRect:rect withRoundingRadius:5.0f];
//Just fill with blue color, do what you want here for the button
[[UIColor blueColor] setFill];
[path fill];
[path addClip]; //Not completely necessary, but borders are actually drawn 'around' the path edge, so that half is inside your path, half is outside adding this will ensure the shadow only fills inside the path
//This strokes the standard path, however you might want to might want to inset the rect, create a new 'back button path' off the inset rect and create the inner shadow path off that.
//The line width of 2.0f will actually show up as 1.0f with the above clip: [path addClip];, due to the fact that borders are drawn around the edge
UIBezierPath *innerShadow = [UIBezierPath bezierPathWithCGPath: CGPathCreateCopyByStrokingPath(path.CGPath, NULL, 2.0f, path.lineCapStyle, path.lineJoinStyle, path.miterLimit)];
//You need this, otherwise the center (inside your path) will also be filled with the gradient, which you don't want
innerShadow.usesEvenOddFillRule = YES;
[innerShadow addClip];
//Now lets fill it with a vertical gradient
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint start = CGPointMake(0, 0);
CGPoint end = CGPointMake(0, CGRectGetMaxY(rect));
CGFloat locations[2] = { 0.0f, 1.0f};
NSArray *colors = [NSArray arrayWithObjects:(id)[UIColor colorWithWhite:.7f alpha:.5f].CGColor, (id)[UIColor colorWithWhite:.3f alpha:.5f].CGColor, nil];
CGGradientRef gradRef = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), (__bridge CFArrayRef)colors, locations);
CGContextDrawLinearGradient(context, gradRef, start, end, 0);
CGGradientRelease(gradRef);
}
现在这只是一个简单的例子。我不保存/恢复上下文或任何你可能想要做的事情。有些事情你可能仍然想做让它变得更好,比如如果你想使用普通边框,可能会插入“阴影”路径。您可能想要使用更多/不同的颜色和位置。但这应该让你开始。
更新
您可以使用另一种方法来创建此效果。我编写了一个算法来斜切核心图形中的任意贝塞尔路径。这可用于创建您正在寻找的效果。这是我如何在我的应用程序中使用它的示例:
您将 CGContextRef、CGPathRef、斜角的大小以及您希望它用于高亮/阴影的颜色传递给例程。
我用于此的代码可以在这里找到:Github - Beveling Algorithm。
我还在这里解释了代码和我的方法:核心图形中的斜切形状