I'm trying to create an own progress bar by subclassing NSProgressIndicator. I wrote the code using a Playground in Xcode 6 and it works fine (the content is being drawn correctly).
As soon as I put the class onto the GUI (either as type for a "Custom View" or for an "Indeterminate Progress Indicator") the control does not draw though the drawRect(dirtyRect: NSRect)
method has been overridden and is being called by the framework.
Here's my code:
class AbProgressBar : NSProgressIndicator
{
let drawStep = 10
var rounded: Bool = true
var margin: CGFloat = 4.0
var barColor: NSColor = NSColor.blueColor()
var barBorderColor: NSColor = NSColor.whiteColor()
var borderColor: NSColor = NSColor.grayColor()
var backgroundColor: NSColor = NSColor.blackColor()
init(coder: NSCoder!)
{
println(__FUNCTION__)
super.init(coder: coder)
}
init(frame frameRect: NSRect)
{
println("\(__FUNCTION__) with frame \(frameRect)")
super.init(frame: frameRect)
}
override func drawRect(dirtyRect: NSRect)
{
println(__FUNCTION__)
// Here we calculate the total value area from minValue to maxValue in order to find out the percental width of the inner bar
let area = minValue < 0 && maxValue < 0 ? abs(minValue) + maxValue : abs(maxValue) + abs(minValue)
let currentPercentageFilled: Double = doubleValue >= maxValue ? maxValue : 100 / area * doubleValue
let innerWidth = (frame.width - (margin * 2)) / 100 * currentPercentageFilled
let radOuterX = rounded ? frame.height / 2 : 0
let radOuterY = rounded ? frame.width / 2 : 0
let radInnerX = rounded ? (frame.height - margin) / 2 : 0
let radInnerY = rounded ? innerWidth / 2 : 0
// The inner frame depends on the width filled by the current value
let innerFrame = NSRect(x: frame.origin.x + margin, y: frame.origin.y + margin, width: innerWidth, height: frame.height - (margin * 2))
let pathOuter: NSBezierPath = NSBezierPath(roundedRect: frame, xRadius: radOuterX, yRadius: radOuterY)
let pathInner: NSBezierPath = NSBezierPath(roundedRect: innerFrame, xRadius: radInnerX, yRadius: radInnerY)
let gradientOuter: NSGradient = NSGradient(startingColor: NSColor.whiteColor(), endingColor: backgroundColor)
let gradientInner: NSGradient = NSGradient(startingColor: NSColor.grayColor(), endingColor: barColor)
gradientOuter.drawInBezierPath(pathOuter, angle: 270.0)
if(pathInner.elementCount > 0)
{
gradientInner.drawInBezierPath(pathInner, angle: 270.0)
}
borderColor.set()
pathOuter.stroke()
barBorderColor.set()
pathInner.stroke()
}
}
Using it within a playground works fine. Setting it as type for a control placed on a UI does NOT work.
Does anybody have any clue what might be wrong?
Edit: Just to add that information: I checked the view using the new "Debug View Hierarchy" feature included in Xcode 6. Result: The control is definitely there.