像这样:
我知道这不适用于NSShadow
,将其绘制进去drawRect:
就可以了。
您可以使用 Core Animations 图层和shadowPath
属性来完成此操作以及许多其他类型的阴影。您所描述的阴影可以使用椭圆阴影路径制作。
产生这个阴影的代码如下。您可以调整椭圆的大小以获得更圆的阴影形状。您还可以使用图层上的阴影属性调整位置、不透明度、颜色和模糊半径。
self.wantsLayer = YES;
NSView *viewWithRoundShadow = [[NSView alloc] initWithFrame:NSMakeRect(30, 30, 200, 100)];
[self addSubview:viewWithRoundShadow];
CALayer *backingLayer = viewWithRoundShadow.layer;
backingLayer.backgroundColor = [NSColor orangeColor].CGColor;
// Configure shadow
backingLayer.shadowColor = [NSColor blackColor].CGColor;
backingLayer.shadowOffset = CGSizeMake(0, -1.);
backingLayer.shadowRadius = 5.0;
backingLayer.shadowOpacity = 0.75;
CGRect shadowRect = backingLayer.bounds;
CGFloat shadowRectHeight = 25.;
shadowRect.size.height = shadowRectHeight;
// make narrow
shadowRect = CGRectInset(shadowRect, 5, 0);
backingLayer.shadowPath = CGPathCreateWithEllipseInRect(shadowRect, NULL);
只是为了展示一些可以使用相同技术创建的其他阴影的示例;像这样的路径
会产生这样的阴影
它远非完美,但我认为它确实会画出你正在寻找的那种阴影。请记住,我留下了一个从全黑到清晰颜色的纯线性渐变。如此黑暗,除非您稍微调整一下值,否则这不会给您带来超逼真的阴影。您可能希望通过添加更多具有不同 alpha 值的位置来使用渐变,以获得您喜欢的任何步进。可能需要进行一些实验,但这些值都可以使用。
根据你的建议,这是drawRect:(CGRect)rect
一回事。只需创建一个自定义视图并仅覆盖它:
- (void)drawRect:(CGRect)rect {
// Get the context
CGContextRef context = UIGraphicsGetCurrentContext();
// Setup the gradient locations. We just want 0 and 1 as in the start and end of the gradient.
CGFloat locations[2] = { 0.0, 1.0 };
// Setup the two colors for the locations. A plain black and a plain black with alpha 0.0 ;-)
CGFloat colors[8] = { 0.0f, 0.0f, 0.0f, 1.0f, // Start color
0.0f, 0.0f, 0.0f, 0.0f }; // End color
// Build the gradient
CGGradientRef gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(),
colors,
locations,
2);
// Load a transformation matrix that will squash the gradient in the current context
CGContextScaleCTM(context,1.0f,0.1f);
// Draw the gradient
CGContextDrawRadialGradient(context, // The context
gradient, // The gradient
CGPointMake(self.bounds.size.width/2,0.0f), // Starting point
0.0f, // Starting redius
CGPointMake(self.bounds.size.width/2,0.0f), // Ending point
self.bounds.size.width/2, // Ending radius
kCGGradientDrawsBeforeStartLocation); // Options
// Release it an pray that everything was well written
CGGradientRelease(gradient);
}
这就是它在我的屏幕上的样子......
我只是在阴影上放置了一个图像,但是如果您继承 UIImageView 并覆盖它的 drawRect 方法,您可以轻松地将阴影与图像合并。
如您所见,我所做的只是简单地设置了一个圆形渐变,但我加载了一个缩放矩阵以在将其绘制到上下文之前将其压缩。如果您打算在该方法中做任何其他事情,请记住您已经准备好矩阵,并且您所做的一切都会被它变形。您可能希望CGContextSaveGState()
在加载矩阵之前保存 CTM,然后使用CGContextRestoreGState()
希望这就是你要找的东西。
干杯。
我可以解释如何在代码中执行此操作,或者解释如何使用为您生成此代码的工具。我选择后者。
使用PaintCode(提供免费演示,每次会话限制 1 小时)。
调整渐变,直到你满意为止。
- (void)viewDidLoad
{
UIImage *natureImage = [UIImage imageNamed:@"nature.jpg"];
CALayer *layer = [CALayer layer];
layer.bounds = CGRectMake(0, 0, 200, 200);
layer.position = CGPointMake(380, 200);
layer.contents = (id)natureImage.CGImage;
layer.shadowOffset = CGSizeMake(0,2);
layer.shadowOpacity = 0.70;
layer.shadowPath = (layer.shadowPath) ? nil : [self bezierPathWithCurvedShadowForRect:layer.bounds].CGPath;
[self.view.layer addSublayer:layer];
}
- (UIBezierPath*)bezierPathWithCurvedShadowForRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPath];
CGPoint topLeft = rect.origin;
CGPoint bottomLeft = CGPointMake(0.0, CGRectGetHeight(rect) + offset);
CGPoint bottomMiddle = CGPointMake(CGRectGetWidth(rect)/2, CGRectGetHeight(rect) - curve);
CGPoint bottomRight = CGPointMake(CGRectGetWidth(rect), CGRectGetHeight(rect) + offset);
CGPoint topRight = CGPointMake(CGRectGetWidth(rect), 0.0);
[path moveToPoint:topLeft];
[path addLineToPoint:bottomLeft];
[path addQuadCurveToPoint:bottomRight controlPoint:bottomMiddle];
[path addLineToPoint:topRight];
[path addLineToPoint:topLeft];
[path closePath];
return path;
}
希望这会帮助你。