Swift - 在阴影层中切割孔

时间:2017-04-05 13:12:45

标签: ios swift swift3 calayer shadow

我想在UIView和Swift3,iOS

的阴影层中“剪一个洞”

我有一个容器(UIView),有两个孩子:

  • 一个UIImageView
  • 在该图像之上的一个UIView(“叠加”)

我想为叠加层添加阴影并剪切阴影的内部矩形,以在ImageView的边缘创建类似发光的效果 由于图像占据了屏幕宽度,所以发光是至关重要的 到目前为止我的代码:

let glowView = UIView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight))
glowView.layer.shadowPath = UIBezierPath(roundedRect: container.bounds, cornerRadius: 4.0).cgPath
glowView.layer.shouldRasterize = true
glowView.layer.rasterizationScale = UIScreen.main.scale
glowView.layer.shadowOffset = CGSize(width: 1.0, height: 1.0)
glowView.layer.shadowOpacity = 0.4

container.addSubview(imageView)
container.addSubview(glowView)

结果如下所示:

image

现在我想切出较暗的内部部分,这样只有边缘的阴影仍然存在 知道如何实现这个目标吗?

3 个答案:

答案 0 :(得分:2)

这几天很容易做到这一点。

enter image description here

这就是全部

import UIKit
class GlowBox: UIView {

    override func layoutSubviews() {
        super.layoutSubviews()

        backgroundColor = .clear
        layer.shadowOpacity = 1
        layer.shadowColor = UIColor.red.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowRadius = 3

        let p = UIBezierPath(
             roundedRect: bounds.insetBy(dx: 0, dy: 0),
             cornerRadius: 4)
        let hole = UIBezierPath(
             roundedRect: bounds.insetBy(dx: 2, dy: 2),
             cornerRadius: 3)
             .reversing()
        p.append(hole)
        layer.shadowPath = p.cgPath
    }
}

答案 1 :(得分:1)

尝试将此作为影子路径:

let shadowWidth = 2.0 // Do this as wide as you want
var outterPath = UIBezierPath()
outterPath.move(to: CGPoint(x: shadowWidth, y: 0))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width, y: 0))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width, y: glowView.bounds.size.height))
outterPath.addLine(to: CGPoint(x: 0.0, y: glowView.bounds.size.height))
outterPath.addLine(to: CGPoint(x: 0.0, y: 0.0))
outterPath.addLine(to: CGPoint(x: shadowWidth, y: 0.0))
outterPath.addLine(to: CGPoint(x: shadowWidth, y: glowView.bounds.size.height - shadowWidth))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - shadowWidth, y: glowView.bounds.size.height - shadowWidth))
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - shadowWidth, y: shadowWidth))
outterPath.addLine(to: CGPoint(x: shadowWidth, y: shadowWidth))
outterPath.close()

这不会创建一个圆形的矩形,但是对上面的代码进行一些更改,你也应该能够添加它们。

答案 2 :(得分:0)

感谢Mihai Fratu's answer我能够创建一个完全符合我需求的UIBezierPath 我在这里发布我的代码,以防有人后来遇到同样的问题

let innerRadius: CGFloat = 32.0 * UIScreen.main.scale
let shadowPath: UIBezierPath = UIBezierPath(roundedRect: self.view.bounds, cornerRadius: self.cornerRadius)
//shadowPath.append(UIBezierPath(roundedRect: self.view.bounds.insetBy(dx: 8, dy: 8), cornerRadius: self.cornerRadius))
let shadowWidth: CGFloat = 8.0 // Do this as wide as you want
var outterPath = UIBezierPath()
// Start at the top left corner with an x offset of the cornerRadius
outterPath.move(to: CGPoint(x: self.cornerRadius, y: 0))

// Draw a line to the top right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - self.cornerRadius, y: 0))
//Draw the round top right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - self.cornerRadius, y: self.cornerRadius), radius: self.cornerRadius, startAngle: (3 * CGFloat.pi) / 2, endAngle: 0, clockwise: true)

// Draw a line to the bottom right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width, y: glowView.bounds.size.height - self.cornerRadius))
// Draw the round bottom right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - self.cornerRadius, y: glowView.bounds.size.height -  self.cornerRadius), radius: self.cornerRadius, startAngle: 0, endAngle: CGFloat.pi / 2, clockwise: true)

// Draw a line to the bottom left corner
outterPath.addLine(to: CGPoint(x: self.cornerRadius, y: glowView.bounds.size.height))
// Draw the round bottom left corner
outterPath.addArc(withCenter: CGPoint(x: self.cornerRadius, y: glowView.bounds.size.height -  self.cornerRadius), radius: self.cornerRadius, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi, clockwise: true)

// Draw a line to the top left corner
outterPath.addLine(to: CGPoint(x: 0.0, y: self.cornerRadius))
// Draw the round top left corner
outterPath.addArc(withCenter: CGPoint(x: self.cornerRadius, y: self.cornerRadius), radius: self.cornerRadius, startAngle: CGFloat.pi, endAngle: (3 * CGFloat.pi) / 2, clockwise: true)

// Move to the inner start point and add the paths counterclockwise to prevent the filling of the inner area
outterPath.move(to: CGPoint(x: shadowWidth + innerRadius, y: shadowWidth))
// Draw the inner top left corner
outterPath.addArc(withCenter: CGPoint(x: shadowWidth + innerRadius, y: shadowWidth + innerRadius), radius: innerRadius, startAngle: (3 * CGFloat.pi) / 2, endAngle: CGFloat.pi, clockwise: false)

// Draw a line to the inner bottom left corner
outterPath.addLine(to: CGPoint(x: shadowWidth, y: glowView.bounds.size.height - innerRadius - shadowWidth))
// Draw the inner bottom left corner
outterPath.addArc(withCenter: CGPoint(x: shadowWidth + innerRadius, y: glowView.bounds.size.height - innerRadius - shadowWidth), radius: innerRadius, startAngle: CGFloat.pi, endAngle: CGFloat.pi / 2, clockwise: false)

// Draw a line to the inner bottom right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - innerRadius - shadowWidth, y: glowView.bounds.size.height - shadowWidth))
// Draw the inner bottom right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - innerRadius - shadowWidth, y: glowView.bounds.size.height - innerRadius - shadowWidth), radius: innerRadius, startAngle: CGFloat.pi / 2, endAngle: 0, clockwise: false)

// Draw a line to the inner top right corner
outterPath.addLine(to: CGPoint(x: glowView.bounds.size.width - shadowWidth, y: shadowWidth + innerRadius))
// Draw the inner top right corner
outterPath.addArc(withCenter: CGPoint(x: glowView.bounds.size.width - innerRadius - shadowWidth, y: shadowWidth + innerRadius), radius: innerRadius, startAngle: 0, endAngle: (3 * CGFloat.pi) / 2, clockwise: false)

// Draw a line to the inner top left corner
outterPath.addLine(to: CGPoint(x: shadowWidth + innerRadius, y: shadowWidth))
outterPath.close()