Nsstatusitem modifier l'image pour teinte foncée

avec OSX 10.10 beta 3, Apple a sorti son option de teinte foncée. Malheureusement, cela signifie également que presque toutes les icônes de barre d'État (à l'exception de Apple et le chemin Finder que j'ai vu), y compris la mienne, restent sombres sur un fond sombre. Comment puis-je fournir une image alternative lorsque la teinte foncée est appliquée?

Je ne vois pas de changement D'API sur NSStatusBar ou NSStatusItem cela me montre un changement, je suppose que c'est une notification ou quelque chose de réactif pour faire facilement le changement que l'utilisateur modifie la teinte.

le code courant pour dessiner l'image est encastré dans un 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;
}
21
demandé sur Vadim Kotov 2014-07-08 08:09:51

5 réponses

TL; DR: vous n'avez pas à faire quoi que ce soit de spécial dans le thème sombre. Donnez NSStatusItem (ou NSStatusBarButton) une image de template et il sera le style correctement dans n'importe quel contexte menubar.


la raison pour laquelle les éléments de statut de certaines applications (comme PathFinder) fonctionnent déjà dans le thème sombre est qu'elles ne paramétrent pas leur propre vue personnalisée sur le StatusItem, mais seulement une image de modèle sur le StatusItem.

quelque Chose comme:

_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
NSImage *image = [NSImage imageNamed:@"statusItemIcon"];
[image setTemplate:YES];
[_statusItem setImage:image];

ce fonctionne exactement comme vous vous y attendiez dans Mavericks et plus tôt, ainsi que Yosemite et toutes les futures versions parce qu'il permet AppKit pour faire tout le style de l'image en fonction de l'état de l'élément de l'état.

Mavericks

dans Mavericks (et plus tôt) il n'y avait que 2 styles uniques des articles. Non habillé et pressé. Ces deux styles semblaient à peu près purement noir et purement blanc, respectivement. (En fait "noir pur" n'est pas tout à fait correct -- était un petit effet qui les a fait paraître légèrement en médaillon).

parce qu'il n'y avait que deux états possibles, les applications de barre d'état pouvaient définir leur propre vue et obtenir facilement la même apparence en dessinant simplement noir ou blanc en fonction de leur état surligné. (Mais notez encore une fois que ce n'était pas purement noir, donc apps a dû construire l'effet dans l'image ou être satisfait avec une icône à peine perceptible hors de place).

Yosemite

à Yosemite il y a au moins 32 style unique d'articles. Unpressed in Dark Theme n'est qu'un de ceux-là. Il n'y a aucune façon pratique (ou non pratique) pour une application d'être capable de faire leur propre style d'articles et avoir l'air correct dans tous les contextes.

Voici des exemples de six de ces styles possibles:

Six possible status item stylings

les articles de statut sur une ménubare inactive ont maintenant un style spécifique, par opposition à un simple changement d'opacité comme dans le passé. L'apparence handicapée est une autre possibilité variation; il y a aussi d'autres dimensions à cette matrice de possibilités.

API

Arbitraire vues comme NSStatusItem view la propriété n'a aucun moyen de capturer toutes ces variations, donc elle (et D'autres API connexes) est dépréciée dans 10.10.

cependant, seed 3 introduit une nouvelle API sur NSStatusItem:

@property (readonly, strong) NSStatusBarButton *button NS_AVAILABLE_MAC(10_10);

Ce morceau de l'API a un peu fins:

  1. Une application peut maintenant obtenir l'écran position (ou afficher un popover à partir d'un élément de statut sans définir sa propre vue personnalisée.
  2. supprime le besoin D'API comme image,title,sendActionOn: sur NSStatusItem.
  3. fournit une classe pour la nouvelle API: i.e. looksDisabled. Cela permet aux applications d'obtenir le style standard Désactivé/Désactivé (comme Bluetooth/Time Machine quand éteint) sans exiger une image personnalisée.

S'il y a quelque chose qui ne peut pas être fait avec L'API current (non - custom view), veuillez déposer un demande d'amélioration. StatusItems devrait fournir le comportement ou les apparences d'une manière qu'il standard à travers tous les éléments de statut.


plus de discussion est à https://devforums.apple.com/thread/234839, bien que j'ai résumé la plupart de tout ici.

57
répondu Taylor 2014-07-09 13:56:56

j'ai fait quelque chose comme suite à ma personnalisé faites glisser et déposez 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 {
        // ...
    }
}

lorsque l'Utilisateur a changé le thème dans Préférences Système, le NSView sera appelé par le système pour re-dessin, vous pouvez changer la couleur de l'icône en conséquence.

si vous souhaitez ajuster d'autres UI personnalisés en dehors de cette vue, vous pouvez utiliser KVO pour observer le isDark clé de la vue ou de le faire sur votre propre.

5
répondu Cai 2014-07-09 16:31:05

j'ai créé un wrapper de base autour de NSStatusItem que vous pouvez utiliser pour fournir le support pour 10.10 et plus tôt avec des vues personnalisées dans la barre d'état. Vous pouvez le trouver ici:https://github.com/noahsmartin/YosemiteMenuBar l'idée de base est de dessiner la vue personnalisée dans un NSImage et d'utiliser cette image comme un modèle d'image pour l'élément de la barre d'état. Ce wrapper transmet également les événements de clic à la vue personnalisée afin qu'ils puissent être traités de la même manière que pre 10.10. Le projet contient une base exemple d'utilisation de YosemiteMenuBar avec une vue personnalisée sur la barre d'état.

2
répondu Noah 2014-07-29 06:39:35

quand votre application a dessiné n'importe quel élément de GUI vous pouvez obtenir son apparence via [NSAppearance currentAppearance] qui elle-même a un name propriété qui contient quelque chose comme

NSAppearanceNameVibrantDark->NSAppearanceNameAqua->NSAppearanceNameAquaMavericks

la première partie est le nom de l'apparence, qui est aussi disponible sous forme de constante dans NSAppearanceNameVibrantDark ou NSAppearanceNameVibrantLight.

je ne sais pas si il y a un moyen d'obtenir juste la première partie, mais je pense que cela fait l'affaire pour l'instant.

exemple de code:

-(void)awakeFromNib {
    NSStatusItem* myStatusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
    myStatusItem.title = @"Hello World";

    if ([[[NSAppearance currentAppearance] name] containsString:NSAppearanceNameVibrantDark]) {
        myStatusItem.title = @"Dark Interface";
    } else {
        myStatusItem.title = @"Light Interface";
    }
}
1
répondu max 2014-07-08 13:49:11

Mais juste au cas où vous ne souhaitez surveiller les changements de statut, vous pouvez. Je sais aussi qu'il y a une meilleure façon de déterminer le mode lite/dark que ce qui a été dit ci-dessus, mais je peux m'en souvenir maintenant.

// Monitor menu/dock theme changes...
[[NSDistributedNotificationCenter defaultCenter] addObserver: self selector: @selector(themeChange:) name:@"AppleInterfaceThemeChangedNotification" object: NULL];

//
-(void) themeChange :(NSNotification *) notification
{
    NSLog (@"%@", notification);
}
1
répondu Alexandra Beebe 2016-02-03 00:27:15