NSStatusItem with custom view, alpha value, and multiple displays - cocoa

I have an app which has a NSStatusItem that uses a custom view. I apply an alpha value to the status item's view when a process in the app in inactive. This works fine, except on OS X 10.9 - 10.10 when multiple displays (monitors) are present. The system menu bar auto-applies an alpha value to itself when it is on an inactive display. On the inactive display, the custom view in my status item seems to completely disappear.
I am guessing that OS X auto-applying an alpha value to the menu bar on the inactive display is combining with the alpha value I am setting directly to the view and causing the view to have an overall alpha value of 0 or less.
Any ideas on how to handle this? Thanks in advance!

As far as I know, to display an inactive NSStatusItem you should use another image, that is the same as the one used when active, but with a grey color (and that image must have template = true).
I guess that applying an alphaValue to the item works just because that is the way that the system uses when a second monitor is attached.

Related

Set color of NSStatusItem OSX 10.10 Swift

I have seen that some icons in the Menu Bar have colours, but I can't find a way to color the NSStatusItem I'm working on. I use an image (inside Images.xcassets) with color, but it just tints in white or black. I'm using MacOS 10.10 and Swift. I have also searched Apple documentation with no luck.
Thanks for your time.
Those status items with color are actually doing it the wrong (old) way. You're supposed to use template images so that the system can apply effects and show it properly in Dark mode. For a template image, the color is ignored. Only the alpha channel matters.
If you really want to defy Apple's recommendation, simply use a non-template image. Don't suffix your image name with "Template" and don't set the template property in code.
From the AppKit release notes for 10.10:
NSStatusItem appearance and Dark Menu support (Section added since WWDC seed)
There are a number of stylistic changes added and supported by
NSStatusItem, including appearance changes for Dark Menus. Template
images should always be used to ensure correct styling based on the
various states the status item can be in (light menu, dark menu,
inactive light, inactive dark, selected, disabled, etc).
NSStatusBarButton’s appearsDisabled property can be used to give the
image a disabled or “off” look without having the item be functionally
disabled. …

Can't disable background blur with NSPopover

I'm having no luck trying to get NSPopover back to its 10.9 appearance when running in 10.10. I have a popover which is attached to an NSView that the user drags around. The popover must be transparent so the user can still see the position of the other UI elements underneath.
All works fine under 10.9 but now under 10.10 with Apple's new gimmicky blurs, I can't seem to get back to the same appearance on 10.10 (unless like me, the user has enabled "Reduce Transparency" in System Preferences > Accessibility. A preference change I can't enforce on end users!).
Have tried:
self.draggingPopover.appearance = NSPopoverAppearanceHUD;
self.popoverView.superview.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
self.popoverView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
None of which make any difference to the popover's appearance on screen.
drawRect in my view subclass fills the background with my chosen color but ignores the alpha value and the popover is opaque.
Similarly I can use self.popoverView.layer.backgroundColor = ... but the alpha value is ignored there too!
Use:
[popover setAppearance:(NSPopoverAppearance)[NSAppearance appearanceNamed:NSAppearanceNameAqua]];
If a requirement is that the popover is transparent (regardless of any future design changes to popover), could you just set the popover window's (i.e. the popoverView's -window) alphaValue to some other value < 1.0?
You can set the Aqua appearance in the storyboard as well. Select the NSPopover's content view and use this setting:

Mavericks and NSStatusItem's custom view with multiple monitors

Since Mavericks each screen has its own status bar. This also means that an application running in the status bar (using NSStatusItem) theoretically has multiple NSStatusItem objects associated. In practice, although the user might see multiple "instances" of your NSStatusItem, it's just one (I've tested this). Now the following problem occurs when you're working with a custom view in your status icon: when the user clicks the status icon, I programmatically "highlight" it using the drawStatusBarBackgroundInRect method. The problem is that each "instance" of the status icon (one per screen) is highlighted although the user just clicked one. This behavior is different from a status icon without a custom view. Is there a way to implement this correctly?
For a good example just click on the Dropbox status icon when you're using multiple displays. You'll notice the selection of the icon on the other screen too.
The response from Apple from mentioned by JLinX Apple Dev Forums' thread:
Status Items with multiple menu bars
10.9 introduces multiple menu bars, each of which draws the status items. If your status item has a custom view, this view is positioned
in one menu bar, and other menu bars get a “clone”, which looks
identical. The clones are not exposed in the API. The clones are
drawn by redirecting your custom view’s drawing into another window.
This means that your status item should not make assumptions about the
drawing destination. For example, it should not assume that a call to
drawRect: is destined for the view’s window, or that the resolution of
the drawing destination matches the resolution of the status item’s
screen. You must also not assume that the status item is on any
particular display, except as described below. The clones are only
redrawn in NSDefaultRunLoopMode. This allows the status item to limit
highlighting to one display, by driving the run loop in another mode,
such as NSEventTrackingRunLoopMode. For example, if you wish to
simulate a menu, you would implement mouseDown: to show your window,
and run the run loop in NSEventTrackingRunLoopMode until you determine
that the window should be dismissed. While the run loop is in this
mode, only the true status item will redraw. Clone status items will
not redraw, and therefore they will not show any highlight applied to
the true status item. When a clone status item is clicked, the clone
exchanges locations with the true status item. This means that the
location and screen of the status item window is reliable from within
mouseDown:. You can access this information from your custom view, for
example, using [[view window] screen] to position a window on the same
screen as the status item.
You question is discussed here. Try to draw your custom view in a run loop other than the default run loop to differentiate between screens...
Alternatively, you can just draw the selection in your view instead of talking to the status item.
- (void)drawRect:(NSRect)dirtyRect
{
if( active )
{
[[NSColor selectedMenuItemColor] set];
NSRectFill(self.bounds);
}
}
this will draw across both your view and the clone.

LongListSelector - Changing the colour of the current selected item

I have a weird situation.
I have a longlistselector with MVVM databinding. When one item get's selected, I change the colour of the text to the phone accent colour. But the item doesn't change its colour on the screen. ( even not when I scroll in the list )
If I then just switch to another page and come back, the item colour is changed if I scroll to it if it is not visible. If it is visible, it still hasn't changed colour until I scroll it out of view and back into view, then the colour will also change.
Anyone the same experience?
If you're changing a bound value but it's not being reflected in the UI then this will typically indicate that you're not correctly notifying of the change. Make sure you're implementing INotifyPropertyChanegd on the viewmodel and calling RaisePropertyChanged appropriately.

Xcode uibutton pressed feedback

I have a number of UIButtons in my app. They are of type custom and are filled with images downloaded from the web. On some pages, when I press a button, it goes darker and so the user knows it has been pressed. On other pages though, nothing happens, and it can sometimes feel like the app is not responding to the user's touch. Is there a way to hard code feedback on button pressed?
UIButton has a property adjustsImageWhenHighlighted, which can be set to YES in order to provide some basic feedback (the image is drawn lighter when the button is highlighted).
By setting showsTouchWhenHighlighted to YES you can get a small highlight indicating a touch on the button.
Other than that you can set different images for different states via - setImage:forState: and - setBackgroundImage:forState:, e.g. for UIControlStateHighlighted or UIControlStateSelected.

Resources