我试图在Cocoa Touch的UIView的底部边缘下画一个阴影。我知道我应该使用CGContextSetShadow()来绘制阴影,但Quartz 2D编程指南有点模糊:

保存图形状态。 调用CGContextSetShadow函数,传递适当的值。 执行要应用阴影的所有绘图。 恢复图形状态

我已经尝试了以下在一个UIView子类:

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    CGContextRestoreGState(currentContext);
    [super drawRect: rect];
}

..但是这对我来说不工作,我有点卡住了(a)下一步要去哪里(b)如果我需要对我的UIView做什么来让这个工作?


当前回答

一个更简单的方法是在初始化时设置视图的一些层属性:

self.layer.masksToBounds = NO;
self.layer.shadowOffset = CGSizeMake(-15, 20);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;

您需要导入QuartzCore。

#import <QuartzCore/QuartzCore.h>

其他回答

在当前代码中,保存当前上下文的GState,配置为绘制阴影。然后将其恢复到您配置它绘制阴影之前的状态。然后,最后,调用超类的drawRect:的实现。

任何应该受到阴影设置影响的绘图都需要在之后进行

CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);

但在

CGContextRestoreGState(currentContext);

如果你想要超类的drawRect:被“包装”在阴影中,那么如果你像这样重新安排你的代码呢?

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    [super drawRect: rect];
    CGContextRestoreGState(currentContext);
}

你可以使用这个扩展来添加阴影

extension UIView {

    func addShadow(offset: CGSize, color: UIColor, radius: CGFloat, opacity: Float)
    {
        layer.masksToBounds = false
        layer.shadowOffset = offset
        layer.shadowColor = color.cgColor
        layer.shadowRadius = radius
        layer.shadowOpacity = opacity

        let backgroundCGColor = backgroundColor?.cgColor
        backgroundColor = nil
        layer.backgroundColor =  backgroundCGColor
    }
}

你可以称之为

your_Custom_View.addShadow(offset: CGSize(width: 0, height: 1), color: UIColor.black, radius: 2.0, opacity: 1.0)
self.layer.masksToBounds = NO;
self.layer.cornerRadius = 8; // if you like rounded corners
self.layer.shadowOffset = CGSizeMake(-15, 20);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;

这将降低应用程序的速度。 添加下面的行可以提高性能,只要你的视图是可见的矩形:

self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;

在Swift 4中使用IBDesignable和IBInspectable绘制阴影

如何使用

Sketch和xcode并排

代码

@IBDesignable class ShadowView: UIView {

    @IBInspectable var shadowColor: UIColor? {
        get {
            if let color = layer.shadowColor {
                return UIColor(cgColor: color)
            }
            return nil
        }
        set {
            if let color = newValue {
                layer.shadowColor = color.cgColor
            } else {
                layer.shadowColor = nil
            }
        }
    }

    @IBInspectable var shadowOpacity: Float {
        get {
            return layer.shadowOpacity
        }
        set {
            layer.shadowOpacity = newValue
        }
    }

    @IBInspectable var shadowOffset: CGPoint {
        get {
            return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height)
        }
        set {
            layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y)
        }

     }

    @IBInspectable var shadowBlur: CGFloat {
        get {
            return layer.shadowRadius
        }
        set {
            layer.shadowRadius = newValue / 2.0
        }
    }

    @IBInspectable var shadowSpread: CGFloat = 0 {
        didSet {
            if shadowSpread == 0 {
                layer.shadowPath = nil
            } else {
                let dx = -shadowSpread
                let rect = bounds.insetBy(dx: dx, dy: dx)
                layer.shadowPath = UIBezierPath(rect: rect).cgPath
            }
        }
    }
}

输出

对于那些没能让这个工作的人(就像我自己一样!),在尝试了所有的答案后,只要确保剪辑子视图没有在属性检查器中启用…