Search code examples
swiftxcodemacosappkit

How to draw NSImage using NSRect or NSView


I'm just newbie about Appkit and macOS programming and I wanna change StatusBar icon while app is working. (Yes, I'm making menu bar app)

the problem is that I could make over 3600 images... No way! that's impossible...

So, All I wanna do is to make computer generate each image and change app's StatusBar icon every seconds.

At first, NSImage is required so change the status bar icon.

Below code is initial code.

statusBar = NSStatusBar.init()
    statusItem = statusBar.statusItem(withLength: 70.0)
    statusBarButton = statusItem.button!

    statusBarButton.image = NSImage(named: NSImage.Name("AppIcon"))
    statusBarButton.image?.size = NSSize(width: 18.0, height: 18.0)
    statusBarButton.imagePosition = .imageRight
    statusBarButton.title = "Menu Bar App"

OK, NSImage(named: NSImage.Name("AppIcon")) is initial app icon image that I prepared before and then I could convert something to NSImage.

I've searched a lot of things about that I can draw image, but nothing seemed proper or appropriate :(

So that's why I'm trying to post this question.

Is there any way to generate image by each seconds?

Please help me


Solution

    • Create a custom NSView with an NSImage property and implement drawRect, simple example

      class MyView: NSView {
      
          var image : NSImage? {
              didSet {
                 needsDisplay = true
              }
          }
      
          init(frame frameRect: NSRect, image : NSImage?) {
              self.image = image
              super.init(frame: frameRect)
          }
      
          required init?(coder: NSCoder) {
              super.init(coder: coder)
          }
      
          override func draw(_ dirtyRect: NSRect) {
              image?.draw(at: .zero, from: bounds, operation: .sourceOver, fraction: 1.0)
          }
      }
      
    • Add an instance of MyView to the subviews of statusBarButton.

    • When an image is assigned to the image property of the view it will be drawn.
    • To change the image periodically use a Timer.