NSStatusItem更改暗色调的图像

Joe*_*her 23 macos objective-c nsstatusitem nsstatusbar osx-yosemite

在OSX 10.10 beta 3中,Apple发布了他们的暗色调选项.不幸的是,这也意味着几乎所有的状态栏图标(除了我见过的Apple和Path Finder),包括我的,都在黑暗的背景下保持黑暗.如何在应用深色调时提供替代图像?

我没有看到API更改NSStatusBarNSStatusItem显示我的更改,我假设它是一个通知或一些反应,以便在用户改变色调时轻松进行更改.

绘制图像的当前代码包含在NSView:

- (void)drawRect:(NSRect)dirtyRect
{
    // set view background color
    if (self.isActive) {
        [[NSColor selectedMenuItemColor] setFill];
    } else {
        [[NSColor clearColor] setFill];
    }

    NSRectFill(dirtyRect);

    // set image
    NSImage *image = (self.isActive ? self.alternateImage : self.image);
    _imageView.image = image;
}
Run Code Online (Sandbox Code Playgroud)

Tay*_*lor 59

TL; DR:你不必在黑暗主题中做任何特别的事情.为NSStatusItem(或NSStatusBarButton)提供模板图像,它将在任何菜单栏上下文中正确设置样式.


某些应用程序的状态项(例如PathFinder)已经在Dark Theme中工作的原因是因为他们没有在StatusItem上设置自己的自定义视图,而只是在StatusItem上设置模板图像.

就像是:

_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
NSImage *image = [NSImage imageNamed:@"statusItemIcon"];
[image setTemplate:YES];
[_statusItem setImage:image];
Run Code Online (Sandbox Code Playgroud)

这与您在Mavericks及其早期以及Yosemite以及任何未来版本中的预期完全一样,因为它允许AppKit根据状态项状态执行图像的所有样式.

小牛

在小牛队(以及之前),只有2种独特的项目风格.没有压力和压力.这两种风格分别看起来纯粹是黑色和纯白色.(实际上"纯黑色"并不完全正确 - 有一个小的效果,使它们看起来有点插入).

因为只有两种可能的状态,状态栏应用程序可以设置自己的视图,只需根据突出显示的状态绘制黑色或白色即可轻松获得相同的外观.(但再次注意,它不是纯粹的黑色,因此应用程序要么必须在图像中构建效果,要么满足于难以察觉的不合适的位置图标).

优胜美地

在优胜美地,至少有32种独特的物品造型.黑暗主题中没有压缩只是其中之一.没有实用(或不实用)的方式让应用程序能够自己设置项目样式并使其在所有上下文中看起来都正确.

以下是六种可能的样式的示例:

六种可能的状态项目样式

非活动菜单栏上的状态项目现在具有特定样式,而不像过去那样简单的不透明度变化.残疾人外表是另一种可能的变化; 这种可能性矩阵还有其他额外的维度.

API

设置为NSStatusItem view属性的任意视图无法捕获所有这些变体,因此它(以及其他相关API)在10.10中已弃用.

但是,种子3在NSStatusItem上引入了新的API:

@property (readonly, strong) NSStatusBarButton *button NS_AVAILABLE_MAC(10_10);
Run Code Online (Sandbox Code Playgroud)

这篇API有一些目的:

  1. 现在,应用程序可以获取状态项的屏幕位置(或显示弹出窗口),而无需设置自己的自定义视图.
  2. 对于删除API一样需要image,title,sendActionOn:上NSStatusItem.
  3. 为新API提供一个类:即looksDisabled.这允许应用程序获得标准的禁用/关闭样式(如关闭时的蓝牙/时间机器),而无需自定义图像.

如果使用当前(非自定义视图)API无法完成某些操作,请为其提交增强请求.StatusItems应该以在所有状态项中标准化的方式提供行为或外观.


更多讨论请访问https://devforums.apple.com/thread/234839,尽管我在这里总结了大部分内容.

  • 您还可以在图像文件名中插入"模板"后缀,例如"MyIconTemplate.png",它将开箱即用.只要提一下这是多么美妙,我能够通过将黑色图标文件的最后8个字符替换为"模板"并使用HEX编辑器编辑已编译构建中的文件引用来破解已编译的应用程序.现在它就像一个魅力!:) (3认同)
  • 注意:在种子3中存在使用`[self.statusItem.button sendActionOn:(NSLeftMouseUpMask | NSRightMouseUpMask)]的问题;`,右键单击事件不会触发.这里有一个开放的雷达:http://openradar.appspot.com/radar?id = 5882037839855616 (2认同)

Cai*_*Cai 5

我最终做了类似跟随我自定义拖放的事情NSStatusItemView:(使用Swift)

var isDark = false

func isDarkMode() {
    isDark = NSAppearance.currentAppearance().name.hasPrefix("NSAppearanceNameVibrantDark")
}

override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)
    isDarkMode()
    // Now use "isDark" to determine the drawing colour.
    if isDark {
        // ...
    } else {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

当用户在系统偏好设置中更改主题时,系统NSView将调用该主题进行重新绘制,您可以相应地更改图标颜色.

如果您希望在此视图外调整其他自定义UI,您可以使用KVO观察isDark视图的键或自行完成.