Подсветка выделения в NSCollectionView

У меня есть работа NSCollectionView за одним незначительным, но критическим, исключением. Получение и выделение выбранного пункта в наборе.

У меня была вся эта работа до Snow Leopard, но что-то, кажется, изменилось, и я не могу вполне поместить палец в него, таким образом, я взял мой NSCollectionView назад к базовому тесту и документации сопровождаемой Apple для создания NSCollectionView здесь:

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

Представление набора хорошо работает после руководства по быстрому началу работы. Однако это руководство не обсуждает выбор кроме "There are such features as incorporating image views, setting objects as selectable or not selectable and changing colors if they are selected".

Используя это как пример я перешел к следующему шагу привязки Контроллера массива к NSCollectionView с ключом контроллера selectionIndexes, думая, что это связало бы любой выбор, который я делаю между NSCollectionView и контроллер массива и таким образом исчерпывание уведомления KVO. Я также установил NSCollectionView можно выбрать в IB.

Кажется, нет никакого делегата выбора к NSCollectionView и в отличие от большей части Какао представления UI, там, кажется, выбранное выделение никакого значения по умолчанию.

Таким образом, моя проблема действительно сводится к связанной проблеме, но двум отличным вопросам.

  1. Как я получаю выбор объекта?
  2. Как я показываю выделение объекта?

NSCollectionViewруководства по программированию, кажется, немногочисленны, и большинство поисков через Google, кажется, тянет реализации перед Snow Leopard или использует представление в отдельном файле XIB.

Для последнего (разделяют файл XIB для представления), я не вижу, почему это должно быть предпосылкой иначе, я подозревал бы, что Apple не будет включать представление в тот же пакет как объект представления набора.

Я знаю, что это будет, "не видят леса для деревьев" проблема - таким образом, я подготовлен к "doh!" момент.

Как обычно, любой и вся справка очень ценятся.

Обновление 1

Хорошо, таким образом, я изобразил нахождение выбранного пункта (пунктов), но должен все же изобразить выделение. Для заинтересованного при расчете выбранных пунктов (принимающий Вас следуют руководству Apple):

В контроллере (в моем тестовом сценарии Делегат Приложения) я добавил следующее:

В awakeFromNib

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

Новый метод

-(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
            }
        }
    }

Не забывайте к dealloc для неGC

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

Все еще ища разрешение выделения...

Обновление 2

Послушал совет Macatomy, но все еще имел проблему. Регистрация соответствующих методов класса видеть, где я пошел не так, как надо.

MyView.h

#import 

@interface MyView : NSView {
    BOOL selected;
}

@property (readwrite) BOOL selected;

@end

MyView.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 
@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

32
задан alecail 16 February 2015 в 17:33
поделиться

1 ответ

Это не слишком сложно сделать. Убедитесь, что "Selection" включен для NSCollectionView в Interface Builder. Затем в подклассе NSView, который вы используете для прототипа представления, объявите свойство "selected" :

@property (readwrite) BOOL selected;

UPDATED CODE HERE: (добавлен вызов super)

Подкласс NSCollectionViewItem и переопределение -setSelected:

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

Затем вам нужно добавить код в метод drawRect: вашего прототипного представления для рисования выделения:

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

Это просто заполняет представление синим цветом, когда оно выбрано, но это можно настроить для рисования выделения любым способом. Я использовал это в своих собственных приложениях, и это отлично работает.

25
ответ дан 27 November 2019 в 20:27
поделиться