Используйте UIBezierPath для маскировки фонового изображения

Я хочу нарисовать полукруглую линию, которая действует как маска для фонового изображения. У меня есть это изображение: изображение Backgound, и я хочу получить это: Маска Я попробовал следующий код, внутри метода рисования пользовательского UIView, но я не знаю, как замаскировать только обведенный путь, а не всю дугу. Что мне не хватает?

      let context = UIGraphicsGetCurrentContext()! 
context.saveGState()

        context.setLineWidth(4)

        path = UIBezierPath()
        path.addArc(withCenter: CGPoint(x: self.bounds.midX, y: self.bounds.height), radius: self.bounds.height-10, startAngle: -180 * CGFloat.pi/180, endAngle: 0 * CGFloat.pi/180, clockwise: true)

        context.addPath(path.cgPath)
        context.replacePathWithStrokedPath()
        context.clip()

        let gradient = CGGradient(colorsSpace: nil, colors: [UIColor.clear.cgColor, UIColor.clear.cgColor] as CFArray, locations: nil)!
        context.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 200, y: 0), options: [])

        context.restoreGState()

        context.saveGState()

        let myLayer = CALayer()
        let myImage = UIImage(named: "color")?.cgImage
        myLayer.frame = self.bounds
        myLayer.contents = myImage

        let maskLayer = CAShapeLayer()
        maskLayer.path = context.path

        myLayer.mask = maskLayer

        self.layer.addSublayer(myLayer)

        context.restoreGState()

1 ответ

В этом методе происходит много всего, чего не должно быть в drawRect - лучше всего избегать drawRect, если вы можете, так как он переносит работу графики на процессор.

Для простоты я показал, как замаскировать изображение с помощью контекста и пути. Проблема в приведенном выше коде заключается в том, что путь невероятно узок и, вероятно, в любом случае находился за пределами видимой части изображения радуги, поэтому я полагаю, что вы ничего не видели много?

При написании такого кода полезно делать это на игровой площадке, чтобы вы могли видеть мгновенные результаты и очень легко настраивать то, что вы делаете. Поглаживание пути также полезно, чтобы увидеть, где вы ожидаете, когда ничего не выглядит правильно. Добавив вашу оригинальную радугу на игровую площадку, я сделал это:

import UIKit

let image = UIImage(named: "I6BbE.jpg")!

let renderer = UIGraphicsImageRenderer(size: image.size)
let maskedImage = renderer.image {
    context in
    let cgContext = context.cgContext
    let bounds = context.format.bounds
    cgContext.setLineWidth(50)

    let path = UIBezierPath()
    path.addArc(
        withCenter: CGPoint(x: bounds.midX, y: bounds.height), 
        radius: bounds.height-100, 
        startAngle: .pi, 
        endAngle: 0, 
        clockwise: true)

    cgContext.addPath(path.cgPath)
    cgContext.replacePathWithStrokedPath()
    cgContext.clip()
    image.draw(in: bounds)
}

maskedImage

Что дает мне:

введите описание изображения здесь

Другие вопросы по тегам