Я призываю вас, боги основной анимации! Я пытаюсь отобразить форму в iOS. Идея состоит в том, чтобы нарисовать квадрат с пунктирными штрихами, внутренним и внешним, как показано на следующем рисунке, созданном с помощью приложения Sketch.
I ' m реализуя его, создавая три слоя, один для внешнего хода, один для внутреннего и один для заливки. Вот мой код:
// setup square properties
let lineDashPattern = [10, 5]
.map({ NSNumber(value: $0) })
let strokeWidth = CGFloat(5)
let frame = CGRect(
x: 40,
y: 40,
width: 119,
height: 119)
let pathBox = CGRect(
x: 0,
y: 0,
width: frame.size.width,
height: frame.size.width)
// Create the container layer
let square = CALayer()
square.frame = frame
// create the fill
let fill = CAShapeLayer()
fill.frame = pathBox
fill.fillColor = UIColor.lightGray.cgColor
fill.path = UIBezierPath(rect: frame).cgPath
// Creater the inner border
let innerBorder = CAShapeLayer()
innerBorder.frame = frame
innerBorder.lineWidth = strokeWidth
innerBorder.strokeColor = UIColor.blue.cgColor
innerBorder.lineDashPattern = lineDashPattern
innerBorder.fillColor = UIColor.clear.cgColor
innerBorder.path = UIBezierPath(rect: pathBox)
.cgPath
.contract(by: strokeWidth / 2)
// Create the outer border
let outerBorder = CAShapeLayer()
outerBorder.frame = frame
outerBorder.lineWidth = strokeWidth
outerBorder.strokeColor = UIColor.red.cgColor
outerBorder.lineDashPattern = lineDashPattern
outerBorder.fillColor = UIColor.clear.cgColor
outerBorder.path = UIBezierPath(rect: pathBox)
.cgPath
.contract(by: -(strokeWidth / 2))
// add all to screen
square.addSublayer(fill)
square.addSublayer(innerBorder)
square.addSublayer(outerBorder)
view.layer.addSublayer(square)
Я также создал следующие расширения в CGPath, чтобы облегчить масштабирование пути фигуры для создания штрихов:
extension CGPath {
func contract(by value: CGFloat) -> CGPath {
let finalBoundingBox = boundingBox.insetBy(
dx: value,
dy: value)
let scaleFactor: CGFloat = finalBoundingBox.width / boundingBox.width
var scaleTransform = CGAffineTransform.identity
.centerScaledBy(x: scaleFactor, y: scaleFactor, bounds: boundingBox)
return copy(using: &scaleTransform)!
}
}
extension CGAffineTransform {
func centerScaledBy(x:CGFloat, y:CGFloat, bounds: CGRect) -> CGAffineTransform {
let center = bounds.center
var xform = self
xform = xform.concatenating(CGAffineTransform(translationX: -center.x, y: -center.y))
xform = xform.concatenating(CGAffineTransform(scaleX: x, y: y))
xform = xform.concatenating(CGAffineTransform(translationX: center.x, y: center.y))
return xform
}
}
extension CGRect {
var center: CGPoint {
return CGPoint(x: self.midX, y: midY)
}
}
Однако результат будет другим , Я получаю полностью смещенные штрихи штрихов, такие как:
Я предполагаю, что Sketch использует слои Core Animation под капотом, поэтому все, что можно сделать с помощью эскиза, должно также воспроизводим по коду, верно?
Заранее спасибо.