How do I create a UIView with a transparent circle inside (in swift)?

前端 未结 4 1395
一生所求
一生所求 2020-12-12 20:30

I want to create a view that looks like this: \"Goal

I figure what I need is a uiview with some sort of

4条回答
  •  囚心锁ツ
    2020-12-12 21:13

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

    Please note that maskLayer.fillRule is set differently between Swift 4 and 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. Create a view sized to the specified frame, with a black background set to 60% opacity
    2. Create the path for drawing the circle using the provided starting point and radius
    3. Create the mask for the area to remove
    4. Apply the mask & clip to bounds

    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)
    

    Which looks like this:

提交回复
热议问题