如何在 swift 中切割 uiview 的边缘

How to cut edges of a uiview in swift

我附上了查看图片。我想在购买按钮和上面的航班信息视图之间实现底部的小切口。

我认为最简单的方法是创建 2 个圆作为普通 UIView 实例,并将它们的中心分别设置为父视图的左右边缘。

由于您将 clipsToBounds 设置为 true,它们将被剪裁,只有一半会在屏幕上可见。

public class TestView: UIView {

    private let leftCircle = UIView(frame: .zero)
    private let rightCircle = UIView(frame: .zero)

    public var circleY: CGFloat = 0
    public var circleRadius: CGFloat = 0

    public override init(frame: CGRect) {
        super.init(frame: frame)
        clipsToBounds = true
        addSubview(leftCircle)
        addSubview(rightCircle)
    }

    public override func layoutSubviews() {
        super.layoutSubviews()

        leftCircle.frame = CGRect(x: -circleRadius, y: circleY,
                                  width: circleRadius * 2 , height: circleRadius * 2)
        leftCircle.layer.masksToBounds = true
        leftCircle.layer.cornerRadius = circleRadius

        rightCircle.frame = CGRect(x: bounds.width - circleRadius, y: circleY,
                                   width: circleRadius * 2 , height: circleRadius * 2)
        rightCircle.layer.masksToBounds = true
        rightCircle.layer.cornerRadius = circleRadius
    }
}

我创建了一个 sample project 来证明这一点。这是它在我的模拟器 (iPhone SE 11.2) 中的样子:

我不得不用阴影来做这个。我尝试创建一个图层并使用 evenOdd fillRule 从中减去另一个图层,但这没有用,因为我需要一个特定的阴影路径,而 evenOdd 应用于路径中的填充。

最后我只是手动创建了路径

func setShadowPath() {
  let path = UIBezierPath()
  path.move(to: bounds.origin)
  path.addLine(to: CGPoint(x: cutoutView.frame.minX, y: bounds.minY))
  path.addArc(withCenter: CGPoint(x: cutoutView.frame.midX, y: bounds.minY),
                radius: cutoutView.bounds.width/2, startAngle: .pi, endAngle: 0, clockwise: false)
  path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
  path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
  path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
  path.close()
    
  layer.shadowPath = path.cgPath
}

我在我的 xib 中创建了一个“cutoutView”,这样我就可以轻松地追踪它。

这使阴影成为正确的形状,然后为了创建剪切本身,我刚刚使用相同的路径创建了一个图层

func setupBackground() {
  let backgroundLayer = CAShapeLayer()
  backgroundLayer.path = layer.shadowPath
  backgroundLayer.fillColor = UIColor.white.cgColor
  layer.insertSublayer(backgroundLayer, at: 0)
}