0

I'm new to swift and to development at all. I'm trying to create a wheel fortune for my app but I'm having some difficulties. I need to be able to set the number of sections of the wheel each time differently. Any help how to do it? I tried to create ellipse like that:

import UIKit

class addShape: UIView {

    let context = UIGraphicsGetCurrentContext();

    override func drawRect(rect: CGRect) {

        CGContextSetLineWidth(context, 3.0)
        //CGContextSetStrokeColorWithColor(context, UIColor.purpleColor().CGColor)

        CGContextStrokeEllipseInRect(context, rect)
        UIColor.redColor().set()

        //Actually draw the path
        CGContextStrokePath(context)
    }
}

but I could not create the ellipse at all :(

I tried this way as well:

override func drawRect(rect: CGRect) {
    ////UTUBE
    UIGraphicsBeginImageContextWithOptions(CGSize(width: 512, height: 512), false, 0)


    // Define the center point of the view where you’ll rotate the arc around
    let center = CGPoint(x:bounds.width/2, y: bounds.height/2)

    // Calculate the radius based on the max dimension of the view.
    let radius: CGFloat = max(bounds.width, bounds.height)

    // Define the thickness of the arc.
    let arcWidth: CGFloat = 115


    /////FIRST Shape
    // Define the start and end angles for the arc.
    let startAngle: CGFloat = 2 * π
    let endAngle: CGFloat = π / 4

    // Create a path based on the center point, radius, and angles you just defined.
    var path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle,
        endAngle: endAngle,
        clockwise: true)

    // Set the line width and color before finally stroking the path.
    path.lineWidth = arcWidth
    counterColor.setStroke()
    path.stroke()


    // Second Shape
    let startAngle2: CGFloat = π / 4
    let endAngle2: CGFloat = π / 2

    // Create a path based on the center point, radius, and angles you just defined.
    path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle2,
        endAngle: endAngle2,
        clockwise: true)

    path.lineWidth = arcWidth
    UIColor.greenColor().setStroke()
    path.stroke()


    // 3rd Shape
    let startAngle3: CGFloat = π / 2
    let endAngle3: CGFloat = 3 * π / 4

    // Create a path based on the center point, radius, and angles you just defined.
    path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle3,
        endAngle: endAngle3,
        clockwise: true)

    path.lineWidth = arcWidth
    UIColor.blueColor().setStroke()
    path.stroke()

    // 4th Shape
    let startAngle4: CGFloat = 3 * π / 4
    let endAngle4: CGFloat = π

    // Create a path based on the center point, radius, and angles you just defined.
    path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle4,
        endAngle: endAngle4,
        clockwise: true)

    path.lineWidth = arcWidth
    UIColor.redColor().setStroke()
    path.stroke()

    // 5th Shape
    let startAngle5: CGFloat = π
    let endAngle5: CGFloat = 5 * π / 4

    // Create a path based on the center point, radius, and angles you just defined.
    path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle5,
        endAngle: endAngle5,
        clockwise: true)

    path.lineWidth = arcWidth
    UIColor.yellowColor().setStroke()
    path.stroke()

    // 6th Shape
    let startAngle6: CGFloat = 5 * π / 4
    let endAngle6: CGFloat = 3 * π / 2

    // Create a path based on the center point, radius, and angles you just defined.
    path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle6,
        endAngle: endAngle6,
        clockwise: true)

    path.lineWidth = arcWidth
    UIColor.grayColor().setStroke()
    path.stroke()

    // 7th Shape
    let startAngle7: CGFloat = 3 * π / 2
    let endAngle7: CGFloat = 7 * π / 4

    // Create a path based on the center point, radius, and angles you just defined.
   path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle7,
        endAngle: endAngle7,
        clockwise: true)

    path.lineWidth = arcWidth
    UIColor.purpleColor().setStroke()
    path.stroke()

    // 8th Shape
    let startAngle8: CGFloat = 7 * π / 4
    let endAngle8: CGFloat = 2 * π

    // Create a path based on the center point, radius, and angles you just defined.
    path = UIBezierPath(arcCenter: center,
        radius: radius/2 - arcWidth/2,
        startAngle: startAngle8,
        endAngle: endAngle8,
        clockwise: true)

    path.lineWidth = arcWidth
    UIColor.lightGrayColor().setStroke()
    path.stroke()

}

I don't think that's the way to do it, but I did not find any other way to do this.

Steve Wilford
  • 8,894
  • 5
  • 42
  • 66
Peter
  • 45
  • 2
  • 10
  • Please format (use correct indentation, don't add unnecessary blank lines) your code properly when posting, it makes it easier for other people to understand. – Steve Wilford Oct 06 '15 at 14:45
  • Using π because you can is self defeating. `M_PI`, `M_PI_2` and `M_PI_4` definitions are already available and more readable. – Abizern Oct 06 '15 at 14:49
  • Is there a way to create ellipse that have dynamic number of sectio? – Peter Oct 06 '15 at 14:57

1 Answers1

0

The main problem with your first example is that your context needs to be retrieved as part of drawRect. Once you have a circle, creating n segments is just a question of drawing n-1 lines.

(Insetting for line width increases complication but looks nicer.)

class WheelView: UIView {

    var pieSections: Int = 1

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func drawRect(rect: CGRect) {
        let context = UIGraphicsGetCurrentContext();
        let lineWidth: CGFloat = 3.0

        // Draw outline
        CGContextSetLineWidth(context, lineWidth)
        UIColor.redColor().set()
        let smaller = rect.insetBy(dx: lineWidth / 2.0, dy: lineWidth / 2.0)
        CGContextStrokeEllipseInRect(context, smaller)

        let radius = smaller.width / 2.0
        let segmentAngle = 2.0 / CGFloat(pieSections) * CGFloat(M_PI)

        // Draw segment dividers
        for index in 1...pieSections {
            let drawAngle = segmentAngle * CGFloat(index)
            let x = radius * cos(drawAngle) + rect.width / 2.0
            let y = radius * sin(drawAngle) + rect.height / 2.0
            CGContextBeginPath(context)
            CGContextMoveToPoint(context, rect.width / 2, rect.height / 2)
            CGContextAddLineToPoint(context, x, y)
            CGContextStrokePath(context)
        }
    }

}
Phillip Mills
  • 30,888
  • 4
  • 42
  • 57