5

像这样:

在此处输入图像描述

我知道这不适用于NSShadow,将其绘制进去drawRect:就可以了。

4

4 回答 4

6

您可以使用 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);

只是为了展示一些可以使用相同技术创建的其他阴影的示例;像这样的路径

在此处输入图像描述

会产生这样的阴影

在此处输入图像描述

于 2013-09-10T08:06:38.163 回答
2

它远非完美,但我认为它确实会画出你正在寻找的那种阴影。请记住,我留下了一个从全黑到清晰颜色的纯线性渐变。如此黑暗,除非您稍微调整一下值,否则这不会给您带来超逼真的阴影。您可能希望通过添加更多具有不同 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()

希望这就是你要找的东西。

干杯。

于 2013-09-10T00:01:54.717 回答
1

我可以解释如何在代码中执行此操作,或者解释如何使用为您生成此代码的工具。我选择后者。

图片

使用PaintCode(提供免费演示,每次会话限制 1 小时)。

  1. 画一个椭圆
  2. 画一个与椭圆底部相交的矩形。
  3. CMD 在左上角的“对象”列表中单击矩形和椭圆形。
  4. 按工具栏中的相交按钮。
  5. 从对象列表中选择贝塞尔曲线。
  6. 将其笔画设置为“无笔画”
  7. 单击渐变按钮(位于左侧,选择检查器下方)
  8. 按“+”按钮
  9. 将渐变颜色更改为浅灰色。
  10. 在选择检查器中,将填充样式更改为“渐变”
  11. 选择渐变:线性

调整渐变,直到你满意为止。

于 2013-09-09T20:45:37.377 回答
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;
}

希望这会帮助你。

于 2013-09-10T08:18:46.830 回答