Используйте 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
Что дает мне: