且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何创建一个内部带有透明圆圈的 UIView(快速)?

更新时间:2022-04-06 05:03:43

再次更新 Swift 4 &删除了一些项目以使代码更紧凑.

Updated again for Swift 4 & removed a few items to make the code tighter.

请注意 maskLayer.fillRule 在 Swift 4 和 Swift 4.2 之间设置不同.

func createOverlay(frame: CGRect,
                   xOffset: CGFloat,
                   yOffset: CGFloat,
                   radius: CGFloat) -> UIView {
    // Step 1
    let overlayView = UIView(frame: frame)
    overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.6)
    // Step 2
    let path = CGMutablePath()
    path.addArc(center: CGPoint(x: xOffset, y: yOffset),
                radius: radius,
                startAngle: 0.0,
                endAngle: 2.0 * .pi,
                clockwise: false)
    path.addRect(CGRect(origin: .zero, size: overlayView.frame.size))
    // Step 3
    let maskLayer = CAShapeLayer()
    maskLayer.backgroundColor = UIColor.black.cgColor
    maskLayer.path = path
    // For Swift 4.0
    maskLayer.fillRule = kCAFillRuleEvenOdd
    // For Swift 4.2
    maskLayer.fillRule = .evenOdd
    // Step 4
    overlayView.layer.mask = maskLayer
    overlayView.clipsToBounds = true

    return overlayView
}

对正在发生的事情的粗略分类:

A rough breakdown on what is happening:

  1. 创建一个尺寸为指定框架的视图,黑色背景设置为 60% 的不透明度
  2. 使用提供的起点和半径创建绘制圆的路径
  3. 为要移除的区域创建遮罩
  4. 敷面膜剪辑到边界

以下代码片段将调用它并在屏幕中间放置一个半径为 50 的圆:

The following code snippet will call this and place a circle in the middle of the screen with radius of 50:

let overlay = createOverlay(frame: view.frame,
                            xOffset: view.frame.midX,
                            yOffset: view.frame.midY,
                            radius: 50.0)
view.addSubview(overlay)

看起来像这样: