我正在使用BezierPath,可以成功地在视图中制作基本的星形,效果很好。但是,视图的大小可以更改。而且,当视图大小更改时,我无法将此贝塞尔曲线路径居中,我设法对其进行缩放,但是居中很难。
private func pointFrom(_ angle: CGFloat, radius: CGFloat, offset: CGPoint) -> CGPoint {
return CGPoint(x: radius * cos(angle) + offset.x, y: radius * sin(angle) + offset.y)//CGPointMake(radius * cos(angle) + offset.x, radius * sin(angle) + offset.y)
}
private func generateStar(width:CGFloat, height:CGFloat, radius:CGFloat) -> CAShapeLayer{
let path = UIBezierPath()
var scale = width / height
if width > height{
scale = height / width
}
let starExtrusion:CGFloat = 60.0
let center = CGPoint(x: width / 2.0, y: height / 2.0)
let pointsOnStar = 5
var angle:CGFloat = -CGFloat(.pi / 2.0)
let angleIncrement = CGFloat(.pi * 2.0 / Double(pointsOnStar))
let radius = width / 2.0
var firstPoint = true
for _ in 1...pointsOnStar {
let point = pointFrom(angle, radius: radius, offset: center)
let nextPoint = pointFrom(angle + angleIncrement, radius: radius, offset: center)
let midPoint = pointFrom(angle + angleIncrement / 2.0, radius: starExtrusion, offset: center)
if firstPoint {
firstPoint = false
path.move(to: point)
}
path.addLine(to: midPoint)//addLineToPoint(midPoint)
path.addLine(to: nextPoint)//addLineToPoint(nextPoint)
angle += angleIncrement
}
path.apply(CGAffineTransform(scaleX: scale, y: scale))
path.close()
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
return maskLayer
}
我如何做到这一点?谢谢!
答案 0 :(得分:2)
路径中心通过以下命令移动:
path.apply(CGAffineTransform(scaleX: scale, y: scale))
要使您的center
居中,请按1 / scale
进行缩放,这样,当scale
对其进行缩放时,它将终止于视图的中心(因为{{ 1}}):
更改:
(1 / scale) * scale == 1
收件人:
let center = CGPoint(x: width / 2.0, y: height / 2.0)
这两个比例相互抵消,然后路径的中心最终到达原来计算的位置。
也就是说,当let center = CGPoint(x: width / 2.0 / scale, y: height / 2.0 / scale)
时,您的星星正在缩小。如果您忘记缩放比例,而只为height != width
计算选择width
和height
中的最小值,则可能会得到更好的结果:
摆脱radius
,或将其设置为scale
,然后
更改:
1.0
收件人:
let radius = width / 2.0
这将使星星尽可能大,同时仍完全适合视图。
正如您所注意到的,随着变小,恒星变“胖”(圆形)。这是因为您有let radius = min(width, height) / 2.0
的{{1}}硬编码常量。该值应基于60.0
。
在计算starExtrusion
之后设置radius
:
starExtrusion
您可以更改radius
乘数以更改星型。
答案 1 :(得分:0)
调整大小时会调用UIView的layoutSubviews
,您可以通过覆盖该方法来重置掩码。