32 votes

Mise en évidence de la sélection dans NSCollectionView

À certaines occasions, ma tête me fait mal juste de la frappant contre le mur de Cacao. Aujourd'hui est un de ces jours.

J'ai un travail NSCollectionView avec un mineur, mais critique, d'exception. Arriver et en mettant en évidence l'élément sélectionné dans la collection.

J'ai eu tout ce travail avant de Snow Leopard, mais quelque chose semble avoir changé et je n'arrive pas à mettre mon doigt sur elle, alors j'ai pris ma NSCollectionView le droit de retour à un test de base et de suivi de la documentation d'Apple pour la création d'un NSCollectionView ici:

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/CollectionViews/Introduction/Introduction.html

L'affichage de la collection des œuvres de l'amende suivant le guide de démarrage rapide. Cependant, ce guide ne traite pas de sélection autre que "There are such features as incorporating image views, setting objects as selectable or not selectable and changing colors if they are selected".

L'utilisation de ce comme un exemple, je suis allé à la prochaine étape de liaison Contrôleur de groupe à l' NSCollectionView avec le contrôleur de la touche selectionIndexes, en pensant que ce serait de lier tout sélection-je faire entre l' NSCollectionView et le contrôleur de matrice et donc de tirer un KVO de notification. J'ai aussi mis l' NSCollectionView pour être sélectionnable dans l'IB.

Il semble y avoir aucune sélection délégué NSCollectionView et contrairement à la plupart de Cacao UI points de vue, il ne semble pas sélectionnée par défaut en surbrillance.

Donc mon problème vient vraiment à une question connexe, mais deux questions distinctes.

  1. Comment faire pour capturer une sélection d'un élément?
  2. Comment puis-je afficher une mise en évidence d'un élément?

NSCollectionView's des guides de programmation semblent être très rares, et la plupart des recherches via Google semblent tirer vers le haut de pré-Snow Leopard mises en œuvre, ou de l'utilisation de la vue dans un autre fichier XIB.

Pour le second (séparée fichier XIB pour la vue), je ne vois pas pourquoi cela devrait être un pré-requis sinon je l'aurais soupçonné que Apple n'aurait pas inclus dans la vue dans le même panier que l'affichage de la collection de l'élément.

Je sais que cela va être "vous ne pouvez pas voir la forêt pour les arbres" question - donc, je suis prêt pour le "doh!" moment.

Comme d'habitude, toute aide appréciée.

Mise à jour 1

OK, j'ai donc pensé trouver l'élément sélectionné(s), mais n'ont pas encore la figure de mettre en évidence. Pour les intéressés à comprendre les éléments sélectionnés (en supposant que vous suivez la Pomme guide):

Dans le contrôleur (dans mon cas de test de l'Application Délégué), j'ai ajouté ce qui suit:

Dans awakeFromNib

[personArrayController addObserver:self
       forKeyPath:@"selectionIndexes" 
       options:NSKeyValueObservingOptionNew
       context:nil];

Nouvelle Méthode

-(void)observeValueForKeyPath:(NSString *)keyPath 
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context
{
    if([keyPath isEqualTo:@"selectionIndexes"])
    {
        if([[personArrayController selectedObjects] count] > 0)
        {
            if ([[personArrayController selectedObjects] count] == 1)
            {
                personModel * pm = (PersonModel *) 
                       [[personArrayController selectedObjects] objectAtIndex:0];
                NSLog(@"Only 1 selected: %@", [pm name]);
            }
            else
            {
                // More than one selected - iterate if need be
            }
        }
    }

N'oubliez pas de dealloc pour les non-GC

-(void)dealloc
{
    [personArrayController removeObserver:self 
                               forKeyPath:@"selectionIndexes"];
    [super dealloc];
}

Toujours à la recherche pour le point culminant de la résolution...

Mise à jour 2

Pris Macatomy les conseils de mais toujours eu un problème. Affichage de la classe pertinente méthodes pour voir où je suis allé mal.

Mavue.h

#import <Cocoa/Cocoa.h>

@interface MyView : NSView {
    BOOL selected;
}

@property (readwrite) BOOL selected;

@end

Mavue.m

#import "MyView.h"

@implementation MyView

@synthesize selected;

-(id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}

-(void)drawRect:(NSRect)dirtyRect
{
    NSRect outerFrame = NSMakeRect(0, 0, 143, 104);
    NSRect selectedFrame = NSInsetRect(outerFrame, 2, 2);

    if (selected)
        [[NSColor yellowColor] set];
    else
        [[NSColor redColor] set];

    [NSBezierPath strokeRect:selectedFrame];
}

@end

MyCollectionViewItem.h

#import <Cocoa/Cocoa.h>
@class MyView;

@interface MyCollectionViewItem : NSCollectionViewItem {

}

@end

"MyCollectionViewItem.m*

#import "MyCollectionViewItem.h"
#import "MyView.h"

@implementation MyCollectionViewItem

-(void)setSelected:(BOOL)flag
{

    [(MyView *)[self view] setSelected:flag];
    [(MyView *)[self view] setNeedsDisplay:YES];
}

@end

34voto

Alternegro Points 521

Si une couleur de fond différente suffira comme une évidence, vous pouvez simplement utiliser un NSBox comme l'élément racine pour vous de la collection de point de vue. Remplissez le NSBox avec la couleur de surbrillance de votre choix. Définir la NSBox à la Coutume de sorte que le remplissage de travail. Définir la NSBox transparent.

Lier l'attribut de transparence de la NSBox à l'attribut sélectionné de Fichier Propriétaire(Point de Collecte) Définissez la valeur du transformateur pour la transparence de la liaison à NSNegateBoolean.

J'ai essayé de joindre Interface builder pour créer des captures d'écran mais j'ai été rejeté bcos je suis un newbie :-(

26voto

indragie Points 9847

Ce n'est pas trop dur à faire. Assurez-vous que la "Sélection" est activée pour le NSCollectionView dans Interface Builder. Puis, dans la NSView sous-classe que vous utilisez pour votre prototype de vue, déclarer une propriété appelée "selected" :

@property (readwrite) BOOL selected;

CODE mis à JOUR ICI: (ajouté super appel)

Sous-classe NSCollectionViewItem et remplacer -setSelected:

- (void)setSelected:(BOOL)flag
{
    [super setSelected:flag];
    [(PrototypeView*)[self view] setSelected:flag];
    [(PrototypeView*)[self view] setNeedsDisplay:YES];
}

Ensuite, vous devez ajouter du code dans votre prototype de la vue drawRect: méthode pour dessiner le clou:

- (void)drawRect:(NSRect)dirtyRect 
{
    if (selected) {
       [[NSColor blueColor] set];
       NSRectFill([self bounds]);
    }
}

Qui remplit la vue en bleu lors de la sélection, mais qui peuvent être personnalisés pour dessiner le point culminant de toute façon que vous voulez. J'ai utilisé dans mes propres applications et il fonctionne très bien.

5voto

Gasper Kolenc Points 98

Vous pouvez également procéder autrement, si vous ne sous-classez pas NSView pour votre vue de protoype.

Dans votre sous-classe NSCollectionViewItem, remplacez setSelected:

 - (void)setSelected:(BOOL)selected
{
    [super setSelected:selected];
    if (selected)
        self.view.layer.backgroundColor = [NSColor redColor].CGColor;
    else
        self.view.layer.backgroundColor = [NSColor clearColor].CGColor;
}
 

Et bien sûr, comme l'ont dit tous les sages avant moi, assurez-vous que la "Sélection" est activée pour NSCollectionView dans Interface Builder.

1voto

GoodSp33d Points 2045

Dans mon cas, je voulais une image(coche) pour indiquer la sélection de l'objet. Faites glisser un ImageWell à l'Élément de la Collection plume. Régler l'image et le marquer comme caché. Aller aux liaisons inspecteur et lier attribut caché à la Vue de Collection de l'Élément.

enter image description here

(Dans mon cas, j'avais créé une plume CollectionViewItem, de sorte que son lié à propriétaire du Fichier. Si ce n'est pas le cas et le Point de vue est dans la même plume que le CollectionView alors se lier à la Collecte d'éléments)

Ensemble de modèle de chemin de clé comme selected et la Valeur transformateur NSNegateBoolean. C'est maintenant à chaque fois que les cellules individuelles/éléments sont sélectionnés, l'image sera visible, et donc indiquant la sélection.

L'ajout de Modifier la réponse.

Pour définir NSBox comme élément racine. Il suffit de créer un nouveau IB document(dire CollectionItem) et faites glisser une NSBox à la zone vide. Maintenant ajouter tous les éléments exigés à l'intérieur de la boîte. Maintenant, cliquez sur le Propriétaire du Fichier et de l'ensemble de la Classe Personnalisée en tant que NSCollectionViewItem.

enter image description here

Et dans la pointe où NSCollectionView est ajouté changer le nom de plume pour CollectionViewItem

enter image description here

Dans le NSBox, lier les éléments restants pour Files Owner. Pour une étiquette, elle serait semblable à :

enter image description here

Maintenant, pour obtenir la couleur de surbrillance comme Alter mentionné dans sa réponse, régler la combinaison de couleurs dans la Couleur de Remplissage de l'option, définissez l' NSBox à la transparence et à lier l'attribut de transparence comme ci-dessous:

enter image description here

Maintenant, lorsque le recouvrement de la Vue des Éléments sont sélectionnés, vous devriez être en mesure de voir la couleur de remplissage de la boîte.

0voto

Rasmus Styrk Points 390

C'était génial, merci beaucoup! je me débattais avec ça!

Pour clarifier pour les autres:

  [(PrototypeView*)[self view] setSelected:flag];
 [(PrototypeView*)[self view] setNeedsDisplay:YES];
 

Remplacez PrototypeView * par le nom du nom de votre classe de prototype.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X