我正在呼唤您,核心动画之神!我正在尝试在iOS中显示形状。这个想法是绘制一个内部和外部带有虚线的正方形,如以下通过Sketch应用创建的图像所示。
我正在实现它,创建了三层,一层用于外部笔触,一层用于内部笔触,一层用于填充。这是我的代码:
// 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图层,所以草图可以完成的所有工作都应该可以通过代码复制,对吧?
提前感谢。
Sketch应用示例中的破折号看起来不像普通破折号–请注意,拐角处的破折号段的长度不均匀。要重新创建它,我只需要使用八个单独的层:四个用于四个内部边缘,然后另外四个用于外部边缘。我会用lineDashPhase来使外边缘的虚线图案与内边缘的虚线图案匹配。