Как создать UIView с прозрачным кругом внутри (в быстром)?

Я хочу создать представление, которое выглядит так: Goal View

Я полагаю, что мне нужен uiview с какой-то маской, я могу сделать маску в форме круга с использованием UIBezierpath, однако я не могу инвертировать это, чтобы он маскировал все, кроме круга. Мне нужно, чтобы это была маска представления, а не слой заполнения, потому что представление, которое я намерен маскировать, имеет UIBlurEffect. Конечная цель состоит в том, чтобы анимировать этот UIView-верхнюю часть моих существующих представлений для предоставления инструкции.

Обратите внимание, что я использую быстро. Есть ли способ сделать это? Если да, то как?

Ответы

Ответ 1

Вы можете использовать эту функцию, чтобы создать то, что вам нужно.

func createOverlay(frame : CGRect)
{
    let overlayView = UIView(frame: frame)
    overlayView.alpha = 0.6
    overlayView.backgroundColor = UIColor.blackColor()
    self.view.addSubview(overlayView)

    let maskLayer = CAShapeLayer()

    // Create a path with the rectangle in it.
    var path = CGPathCreateMutable()

    let radius : CGFloat = 50.0
    let xOffset : CGFloat = 10
    let yOffset : CGFloat = 10

    CGPathAddArc(path, nil, overlayView.frame.width - radius/2 - xOffset, yOffset, radius, 0.0, 2 * 3.14, false)
    CGPathAddRect(path, nil, CGRectMake(0, 0, overlayView.frame.width, overlayView.frame.height))


    maskLayer.backgroundColor = UIColor.blackColor().CGColor

    maskLayer.path = path;
    maskLayer.fillRule = kCAFillRuleEvenOdd

    // Release the path since it not covered by ARC.
    overlayView.layer.mask = maskLayer
    overlayView.clipsToBounds = true
}

Отрегулируйте значения radius и xOffset и yOffset, чтобы изменить радиус и положение круга.

Ответ 2

Для Swift 3 отформатирован ответ rakeshbs, поэтому он возвращает UIView:

func createOverlay(frame : CGRect, xOffset: CGFloat, yOffset: CGFloat, radius: CGFloat) -> UIView
{
    let overlayView = UIView(frame: frame)
    overlayView.alpha = 0.6
    overlayView.backgroundColor = UIColor.black

    // Create a path with the rectangle in it.
    let path = CGMutablePath()
    path.addArc(center: CGPoint(x: xOffset, y: yOffset), radius: radius, startAngle: 0.0, endAngle: 2 * 3.14, clockwise: false)
    path.addRect(CGRect(x: 0, y: 0, width: overlayView.frame.width, height: overlayView.frame.height))

    let maskLayer = CAShapeLayer()
    maskLayer.backgroundColor = UIColor.black.cgColor
    maskLayer.path = path;
    maskLayer.fillRule = kCAFillRuleEvenOdd

    // Release the path since it not covered by ARC.
    overlayView.layer.mask = maskLayer
    overlayView.clipsToBounds = true

    return overlayView
}

Ответ 3

Обновлено для Swift 4 и удалено несколько элементов, чтобы сделать код более плотным.

func createOverlay(frame : CGRect, xOffset: CGFloat, yOffset: CGFloat, radius: CGFloat) -> UIView
{
    let overlayView = UIView(frame: frame)
    overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.6)

    let path = CGMutablePath()
    path.addArc(center: CGPoint(x: xOffset, y: yOffset), radius: radius, startAngle: 0.0, endAngle: 2.0 * CGFloat.pi, clockwise: false)
    path.addRect(CGRect(origin: .zero, size: overlayView.frame.size))

    let maskLayer = CAShapeLayer()
    maskLayer.backgroundColor = UIColor.black.cgColor
    maskLayer.path = path
    maskLayer.fillRule = kCAFillRuleEvenOdd

    overlayView.layer.mask = maskLayer
    overlayView.clipsToBounds = true

    return overlayView
}

Грубая разбивка по тому, что происходит:

  • Создайте представление размером до указанного фрейма с черным фоном, установленным на 60% непрозрачность
  • Создайте путь для рисования круга, используя предоставленную начальную точку и радиус
  • Создайте маску для области для удаления.
  • Применить маску и клип к границам

Следующий фрагмент кода вызовет это и поместит круг в середину экрана с радиусом 50:

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

Что выглядит так: введите описание изображения здесь