简体   繁体   中英

Making sunburst in Swift with a UIBezierPath

I want to make this UIView with UIBezierPath:

在此处输入图片说明

With the optional ability to spin it (although I can make this on my own if I know how to draw that sunburst (that is how I call the view))

Here the answer is given in Objective C: https://stackoverflow.com/a/14991292/7715250

I tried to convert it in Swift with this code (copy-paste in Playground will work):

import UIKit

class SunBurst: UIView{
    override func draw(_ rect: CGRect) {
        let radius: CGFloat = rect.size.width / 2.0
        UIColor.red.setFill()
        UIColor.blue.setStroke()
        let bezierPath = UIBezierPath()
        let centerPoint = CGPoint(x: rect.origin.x + radius, y: rect.origin.y + radius)
        var thisPoint = CGPoint(x: centerPoint.x + radius, y: centerPoint.y)
        bezierPath.move(to: centerPoint)
        var thisAngle: CGFloat = 0.0
        let sliceDegrees: CGFloat = 360.0 / 20 / 2.0
        let half: CGFloat = 180
        let floatRadius = Float(radius)

        for _ in 0..<20 {
            let x = CGFloat((floatRadius * cosf(Float(.pi * thisAngle + sliceDegrees / half)))) + centerPoint.x
            let y = CGFloat((floatRadius * sinf(Float(.pi * thisAngle + sliceDegrees / half)))) + centerPoint.y
            thisPoint = CGPoint(x: x, y: y)
            bezierPath.addLine(to: thisPoint)
            thisAngle += sliceDegrees
            let x2 = CGFloat((floatRadius * cosf(Float((.pi * thisAngle + sliceDegrees) / half)))) + centerPoint.x
            let y2 = CGFloat((floatRadius * sinf(Float((.pi * thisAngle + sliceDegrees) / half)))) + centerPoint.y
            thisPoint = CGPoint(x: x2, y: y2)
            bezierPath.addLine(to: thisPoint)
            bezierPath.addLine(to: centerPoint)
            thisAngle += sliceDegrees
        }
        bezierPath.close()
        bezierPath.lineWidth = 1
        bezierPath.fill()
        bezierPath.stroke()
    }
}


let custom = SunBurst(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
custom.backgroundColor = .clear

With this result:

在此处输入图片说明

I think I am missing 1 line of code since it almost looks correct, but what what am I missing? I am surely not an expert with Objective C and I used https://objectivec2swift.com/#/home/converter/ to convert the code on the link with the answer.

Besides it almost looks correct, it should work in landscape mode. When I lower the height and retain the same width, the sunburst fails badly to draw. How can it also work in landscape?

Thanks for any help making the correct UIView. I think it would look nice for a bonus view in a game.

The problem is a lack of proper operator precedence in your degree to radian calculation.

Replace each use (all four lines) of:

.pi * thisAngle + sliceDegrees / half

with:

.pi * (thisAngle + sliceDegrees) / half

Better, add a degreesToRadians function so you can simply pass thisAngle + sliceDegrees to it and avoid the problem all together.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM