Billy S Billy S - 1 month ago 20
Swift Question

swift - error when drawing curve

I am attempting to write a program that draws a curve. The shorter the curve, the closer to green it gets. Here is the code for drawing the circle:

func drawCircle(percent: CGFloat) {
// Set up all the data for the circle
let redAmt = 1 / 100 * percent
let greenAmt = 1 - redAmt
let circleColor = UIColor.init(red: redAmt, green: greenAmt, blue: 0, alpha: 1)
let lineWidth = CGFloat(12)
let centerX = self.frame.size.width / 2
let centerY = self.frame.size.height / 2
let radius = (self.frame.size.width - lineWidth) / 2
// Clear the area where the circle is going to be drawn
let clearCirclePath = UIBezierPath(arcCenter: CGPoint(x: centerX, y: centerY), radius: radius, startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2), clockwise: true)
clearColor.setStroke()
clearCirclePath.lineWidth = lineWidth
clearCirclePath.stroke()
// Draw the circle
let circlePath = UIBezierPath(arcCenter: CGPoint(x: centerX, y: centerY), radius: radius, startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2) * percent / 100, clockwise: true)
circleColor.setStroke()
circlePath.lineWidth = lineWidth
circlePath.stroke()
}


It works just fine when called by
drawRect(rect: CGRect)
, but when I try to call in another file, it does not work. It is drawing the arc in a view inside a view controller. The error it gives me is this:
ExerciseTracker[7270] <Error>: CGContextSetStrokeColorWithColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.


Thanks a lot!

(I am using Xcode 7.3.1)

Answer

You must draw in a valid context. drawRect: provides such a valid context. Simply putting code outside of drawRect: doesn't work unless you explicitly create your own context such as a bitmap context for creating an image by drawing.

The code in your drawCircle method needs to be in the drawRect: method of a custom view class. Instead of passing percent as a parameter, set it as an instance variable. Then anytime you update the value of percent, you call setNeedsDisplay() to trigger the view to redraw itself.