如何缩放和居中UIBezierPath?

时间:2019-09-07 06:47:27

标签: ios swift uibezierpath

我正在使用BezierPath,可以成功地在视图中制作基本的星形,效果很好。但是,视图的大小可以更改。而且,当视图大小更改时,我无法将此贝塞尔曲线路径居中,我设法对其进行缩放,但是居中很难。

enter image description here image2

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
}

我如何做到这一点?谢谢!

2 个答案:

答案 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计算选择widthheight中的最小值,则可能会得到更好的结果:

摆脱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,您可以通过覆盖该方法来重置掩码。