Я столкнулся с проблемой, когда я пытаюсь установить простой путь для CAShapeLayer
, который, в свою очередь, находится в трехмерном преобразованном родительском виде / слое. Для некоторых преобразований, которые я хочу использовать, слой будет проходить по пути, отличному от того, который заполнен цветом заливки.
Я создал образец, который покажет этот эффект. Артефакты могут быть видны с различными формами и преобразованиями, по крайней мере, если форма включает кривые Безье и преобразование имеет перспективу и вращение.
Есть ли решение для этого? Я в порядке с заполненной областью, которая несколько искажается, пока штрих идет по заполненному пути.
// Create a single view app and paste this as the main view controller to test
class ViewController: UIViewController {
var shapeView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
shapeView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
let layer = createShapeLayer()
layer.frame = shapeView.bounds
layer.path = createPath()
shapeView.layer.addSublayer(layer)
shapeView.layer.transform = getTransform()
view.addSubview(shapeView)
}
func createShapeLayer() -> CAShapeLayer {
let layer = CAShapeLayer()
layer.fillColor = UIColor.red.cgColor
layer.strokeColor = UIColor.black.cgColor
layer.lineWidth = 5
return layer
}
func getTransform() -> CATransform3D {
var transform = CATransform3DIdentity
transform.m34 = 1.0 / -76.28
transform = CATransform3DTranslate(transform, 0.0, 59.59, 50.45)
transform = CATransform3DRotate(transform, 147.43 * .pi / 180.0, 1.0, 0.0, 0.0)
return transform
}
// Simple banana shape
func createPath() -> CGPath {
let path = CGMutablePath()
path.move(to: CGPoint(x: 45, y: 0))
let cp1 = CGPoint(x: 50, y: -25)
path.addCurve(to: CGPoint(x: 55, y: 0), control1: cp1, control2: cp1)
let cp2 = CGPoint(x: 80, y: 50)
path.addCurve(to: CGPoint(x: 55, y: 100), control1: cp2, control2: cp2)
let cp3 = CGPoint(x: 50, y: 125)
path.addCurve(to: CGPoint(x: 45, y: 100), control1: cp3, control2: cp3)
let cp4 = CGPoint(x: 70, y: 50)
path.addCurve(to: CGPoint(x: 45, y: 0), control1: cp4, control2: cp4)
return path
}
}
Вот как выглядит результат. Одна фигура с красным цветом заливки и черным цветом обводки.
Я подозреваю, что проблема заключается в том, что алгоритм заполнения нарушается в некоторых случаях, а алгоритм обводки - нет. Области, которые должны быть заполнены, становятся очень большими в направлении Z, хотя и маленькими на экране. Тем не менее, в идеале я думаю, что обводка всегда должна находиться на краю заполненной области, даже если она искажается.