绘制阴影的UIView仅可从3面(Draw shadow only from 3 sides of

2019-08-18 05:43发布

我已经成功地实现绘制阴影在我UIView是这样的:

block1.layer.masksToBounds = NO;
block1.layer.shadowOffset = CGSizeMake(0, 0);
block1.layer.shadowRadius = 1;
block1.layer.shadowOpacity = 0.7;

现在会发生什么是我有一个长方形UIView ,我想提请阴影周围三面,留下它的底部 没有影子。

我知道,我必须指定block1.layer.shadowPath通过创建一个新UIBezierPath ,但我不知道该怎么做。

显然,设置layer.shadowOffset不会为我做的伎俩。

提前致谢!

Answer 1:

我知道你说的设置layer.shadowOffset不会为你工作,但你被允许投入是负值,因此将其设置layer.shadowOffset = CGSizeMake(0.0, -2.0)会来接近你要找的效果,但我当然希望你希望它是即使在三个方面。

所以在这里,我们一起去layer.shadowPath

UIView *block1 = [[UIView alloc] initWithFrame:CGRectMake(32.0, 32.0, 128.0, 128.0)];
[block1 setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:block1];

block1.layer.masksToBounds = NO;
block1.layer.shadowOffset = CGSizeMake(0, 0);
block1.layer.shadowRadius = 1;
block1.layer.shadowOpacity = 0.7;

UIBezierPath *path = [UIBezierPath bezierPath];

// Start at the Top Left Corner
[path moveToPoint:CGPointMake(0.0, 0.0)];

// Move to the Top Right Corner
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame), 0.0)];

// Move to the Bottom Right Corner
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame), CGRectGetHeight(block1.frame))];

// This is the extra point in the middle :) Its the secret sauce.
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame) / 2.0, CGRectGetHeight(block1.frame) / 2.0)];

// Move to the Bottom Left Corner
[path addLineToPoint:CGPointMake(0.0, CGRectGetHeight(block1.frame))];

// Move to the Close the Path
[path closePath];

block1.layer.shadowPath = path.CGPath;

并给你一个想法怎么回事,这里是你刚刚绘制的实际阴影路径:)

它可能只是转移额外的中间点之前或之后的其他线路选择哪一方将被省略。



Answer 2:

改进对其他的答案,这要归功于有点阿肖克- [R为SWIFT代码。

因为我们正在创建在所有两侧阴影视图的背景对双方阴影三角形视图,以及一个白色三角形不需要。

它打破在与宽度比相对高度大的观点的情况。

一种解决方法将是路径转移,而不是完全地创建三角形视图路径用于在不需要阴影一点朝向的观点,即侧的线。

我创建为一个扩展 -

extension UIView {
    func addshadow(top: Bool,
                   left: Bool,
                   bottom: Bool,
                   right: Bool,
                   shadowRadius: CGFloat = 2.0) {

        self.layer.masksToBounds = false
        self.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
        self.layer.shadowRadius = shadowRadius
        self.layer.shadowOpacity = 1.0

        let path = UIBezierPath()
        var x: CGFloat = 0
        var y: CGFloat = 0
        var viewWidth = self.frame.width
        var viewHeight = self.frame.height

        // here x, y, viewWidth, and viewHeight can be changed in
        // order to play around with the shadow paths.
        if (!top) {
            y+=(shadowRadius+1)
        }
        if (!bottom) {
            viewHeight-=(shadowRadius+1)
        }
        if (!left) {
            x+=(shadowRadius+1)
        }
        if (!right) {
            viewWidth-=(shadowRadius+1)
        }
        // selecting top most point
        path.move(to: CGPoint(x: x, y: y))
        // Move to the Bottom Left Corner, this will cover left edges
        /*
         |☐
         */
        path.addLine(to: CGPoint(x: x, y: viewHeight))
        // Move to the Bottom Right Corner, this will cover bottom edge
        /*
         ☐
         -
         */
        path.addLine(to: CGPoint(x: viewWidth, y: viewHeight))
        // Move to the Top Right Corner, this will cover right edge
        /*
         ☐|
         */
        path.addLine(to: CGPoint(x: viewWidth, y: y))
        // Move back to the initial point, this will cover the top edge
        /*
         _
         ☐
         */        
        path.close()
        self.layer.shadowPath = path.cgPath
    }

并设置逻辑真为你想要的影子不论哪一方出现

myView.addshadow(top: false, left: true, bottom: true, right: true, shadowRadius: 2.0)

//阴影半径是上述可选的,并且在2.0被设置为默认

myView.addshadow(top: true, left: true, bottom: true, right: true, shadowRadius: 2.0)

myView.addshadow(top: false, left: false, bottom: true, right: true, shadowRadius: 2.0)



Answer 3:

更新瑞安Poolos回答斯威夫特3.0

由于瑞安Poolos

class sampleViewController: UIViewController {
    var block1: UIView! = nil

    override func viewDidLoad() {

        super.viewDidLoad()
        block1 = UIView(frame: CGRect(x: 32.0, y: 32.0, width: 128.0, height: 128.0))
        block1.backgroundColor = UIColor.orange
        self.view.addSubview(block1)

        block1.layer.masksToBounds = false
        block1.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
        block1.layer.shadowRadius = 1.0
        block1.layer.shadowOpacity = 0.7

        let path = UIBezierPath()

        // Start at the Top Left Corner
        path.move(to: CGPoint(x: 0.0, y: 0.0))

        // Move to the Top Right Corner
        path.addLine(to: CGPoint(x: block1.frame.size.width, y: 0.0))

        // Move to the Bottom Right Corner
        path.addLine(to: CGPoint(x: block1.frame.size.width, y: block1.frame.size.height))

        // This is the extra point in the middle :) Its the secret sauce.
        path.addLine(to: CGPoint(x: block1.frame.size.width/2.0, y: block1.frame.size.height/2.0))

        // Move to the Bottom Left Corner
        path.addLine(to: CGPoint(x: 0.0, y: block1.frame.size.height))

        path.close()

        block1.layer.shadowPath = path.cgPath
    }
}

结果:



Answer 4:

试试这个

extension CALayer {
func applySketchShadow(color: UIColor, alpha: CGFloat, x: CGFloat, y: CGFloat, blur: CGFloat, spread: CGFloat)
{
    shadowColor = color.cgColor
    shadowOpacity = alpha
    shadowOffset = CGSize(width: x, height: y)
    shadowRadius = blur / 2.0
    if spread == 0 {
        shadowPath = nil
    } else {
        let dx = -spread
        let rect = bounds.insetBy(dx: dx, dy: dx)
        shadowPath = UIBezierPath(rect: rect).cgPath
    }
}


文章来源: Draw shadow only from 3 sides of UIView