tags:

views:

1017

answers:

2

In my small app for Mac OS X I display some info in system menubar. I use

statusItem = [
  [[NSStatusBar systemStatusBar]
   statusItemWithLength:NSVariableStatusItemLength]
   retain
];

It works very nice and I can change the text with

[statusItem setTitle:[NSString stringWithString:@"Woo-hoo"]];

But it uses the default menu font which is too big for my relatively unimportant info. So I decided to reimplement it with a custom view. I created a view in Interface Builder.

Unfortunately, however, when I set it as a view for my menu item with

[statusItem setView:myView];

it just displays a white bar in the menu instead of my thing. I tried to

[statusItem 
  drawStatusBarBackgroundInRect:[myView frame]
  withHighlight:NO];

with no success.

In trying to figure out whether a problem is with the view itself or with the way I assign it to the menubar, I created a window and did

[myTestWindow setContentView:myView];

This one worked seamlessly. This makes me think my view is OK :-)

So, what else can I try to make the menu item display my own view?

Thanks!

+2  A: 

What is the height of the frame of the view? Maybe your view is taller than the menubar and you are drawing outside of it. The current menubar is 22 pixels, but you should ask the systemStatusBar for it's thickness, just in case it ever changes.

Try drawing a frame around your view to see if you are getting anything.

[[NSColor blueColor] set];
NSBezierPath *path = [NSBezierPath bezierPathWithRect:self.bounds];
[path setLineWidth:4.0f];
[path stroke];

If you get just an 'L' shape (the bottom left corner) of blue then the view is too large. If you get a rectangle but still no text then you may not be drawing the text inside the view, look at the coordinates you are drawing the text at (and review View Geometry). Putting the view in a window may have worked because it is larger.

For an example of using text in a status menu view take a look at Matt Gemmell's NSStatusItemTest project.

EDIT:

Sorry, somehow I missed where you said you created the view in IB. I did a quick test and I can see the white box you mentioned.

The docs for NSStatusItem's setView: states

The custom view is responsible for drawing itself and providing its own behaviors, such as processing mouse clicks and sending action messages.

And status item views go into a special (apple private) window called NSStatusBarWindow that may have different internal behavior than normal windows and certainly seems to not support views from IB.

So yes, I think you need to create a custom NSView subclass and do your own drawing in drawrect:.

Nathan Kinsinger
Height of my view is exactly 22 pixels. Does your code example go into drawRect implementation? Actually, I don’t even implement it, should I? I thought it would draw itself automatically since I’ve made it in IB. Thanks.
Ilya Birman
Thanks for additional info you mentined in your edit. I actually saw this line in the doc, but didn’t know what follows :-) In case drawRect:ing works for me, I’ll accept your answer later. Anyway, it seems weird you can’t just use view from IB...
Ilya Birman
Awright, I won: it happened to be some weird side-effects of window-view autosizing setup in IB. I re-configured the sizing in IB, and now it works perfectly. Let’s call this kind of side-effects, the *size-effects*
Ilya Birman
Oh, and drawRect: didn’t help, it also worked only in window, not in menu item.
Ilya Birman
+3  A: 

It happened to be some weird side-effects of window-view autosizing setup in Interface Builder (let’s call them size-effects). In the Inspector you can setup how subviews get resized upon superview sizing. And so it was somehow broken in my case, such that when window gets small enough (menuitem-high), my elements just got drawn outside of the window’s frame.

I re-configured the sizing in IB, eliminating all the automatics I don’t need, and now it works perfectly: the view from IB gets displayed inside a menu item.

Ilya Birman
Could you be more specific about what you did in IB? I have this same problem, and I've partially fixed it by getting rid of the struts/springs in IB. I can now see part of my view, but the bounds are weird and so it is off-center.
Kristopher Johnson