I have created a custom NSLevelIndicator
which can display a string value within it. Below is the code for it. I tested this in a storyboard OSX app and it works well.
import Cocoa
class CustomLevelIndicator: NSLevelIndicator {
var text: String!
private var textField: NSTextField!
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
}
override func awakeFromNib() {
textField = NSTextField()
textField.stringValue = text
textField.bezeled = false
textField.drawsBackground = false
textField.editable = false
textField.selectable = false
textField.textColor = NSColor.blackColor()
textField.font = NSFont.systemFontOfSize(12)
textField.translatesAutoresizingMaskIntoConstraints = false
addSubview(textField, positioned: .Above, relativeTo: nil)
let xCenterConstraint = NSLayoutConstraint(item: textField, attribute: .CenterX, relatedBy: .Equal, toItem: self, attribute: .CenterX, multiplier: 1, constant: 0)
let yCenterConstraint = NSLayoutConstraint(item: textField, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: 1, constant: 0)
addConstraints([xCenterConstraint, yCenterConstraint])
}
}
Now I'm trying to use the same control in a menu bar app. Here's the view layout of it.
The code of the menu object.
class ProgressMenuController: NSObject {
@IBOutlet weak var menu: NSMenu!
@IBOutlet weak var progressView: ProgressView!
let menuItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSVariableStatusItemLength)
var progressMenuItem: NSMenuItem!
override func awakeFromNib() {
menuItem.menu = menu
menuItem.image = NSImage(named: "icon")
progressMenuItem = menu.itemWithTitle("Progress")
progressMenuItem.view = progressView
progressView.update(42)
}
@IBAction func quitClicked(sender: NSMenuItem) {
NSApplication.sharedApplication().terminate(self)
}
}
The code for the view that has the level indicator.
import Cocoa
class ProgressView: NSView {
@IBOutlet weak var progressIndicator: CustomLevelIndicator!
func update(value: Double) {
dispatch_async(dispatch_get_main_queue()) {
self.progressIndicator.doubleValue = value
self.progressIndicator.text = "\(value)%"
}
}
}
The problem is the text in custom level indicator doesn't show up. And the level indicator has some sort of a dark overlay.
I can't figure out why this is happening. In my actual app, the values for this indicator is updated periodically via a network request that executes in a background thread. That's why I update the UI in the main thread specifically in the update()
function. I took the code inside the closure and put it outside just to test, still it doesn't work. Note that the problem is with assigning the value for the text
property and not the doubleValue
as you can see the level indicator's value is updated properly but not the text. I'm kinda stumped now.
Any help is appreciated. I uploaded a demo project here as well.