Создание пустых выделений в NSCollectionView - PullRequest
3 голосов
/ 09 января 2012

Я настроил NSCollectionView в приложении какао. Я подклассифицировал NSCollectionViewItem представления коллекции, чтобы отправить мне пользовательский NSNotification, когда одно из его представлений выбрано / снято. Я зарегистрировался, чтобы получить уведомление в моем объекте контроллера, когда это уведомление отправлено. В этом методе я сообщаю только что выбранному представлению, что оно выбрано, и говорю ему перерисовать, что делает его серым.

Подкласс NSCollectionViewItem:

-(void)setSelected:(BOOL)flag {
[super setSelected:flag];

[[NSNotificationCenter defaultCenter] postNotificationName:@"ASCollectionViewItemSetSelected" 
                                                    object:nil 
                                                  userInfo:[NSDictionary dictionaryWithObjectsAndKeys:(ASListView *)self.view, @"view", 
                                                            [NSNumber numberWithBool:flag], @"flag", nil]];}

Класс контроллера (в методе -(void)awakeFromNib):

//Register for selection changed notification
[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(selectionChanged:) 
                                             name:@"ASCollectionViewItemSetSelected" 
                                           object:nil];

И метод -(void)selectionChanged:(NSNotification *)notification:

- (void)selectionChanged:(NSNotification *)notification {
// * * Must get the selected item and set its properties accordingly

//Get the flag
NSNumber *flagNumber = [notification.userInfo objectForKey:@"flag"];
BOOL flag = flagNumber.boolValue;

//Get the view
ASListView *listView = [notification.userInfo objectForKey:@"view"];

//Set the view's selected property
[listView setIsSelected:flag];
[listView setNeedsDisplay:YES];

//Log for testing
NSLog(@"SelectionChanged to: %d on view: %@", flag, listView);}

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

.

-(void)setSelectionIndexes:(NSIndexSet *)indexes

Но всегда возникает ситуация, которая приводит к пустому выделению в представлении коллекции.

Так что мне было интересно, есть ли более простой способ предотвратить пустое выделение в NSCollectionView? Я не вижу флажок в конструкторе интерфейса.

Заранее спасибо!

Ben

Обновление

В итоге я просто подклассифицировал свой NSCollectionView и переопределил - (void)mouseDown:(NSEvent *)theEvent метод. Я только тогда отправил метод [super mouseDown:theEvent];, если клик был в одном из подпредставлений. Код:

- (void)mouseDown:(NSEvent *)theEvent {
NSPoint clickPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];

int i = 0;
for (NSView *view in self.subviews) {
    if (NSPointInRect(clickPoint, view.frame)) {
        //Click is in rect
        i = 1;
    }
}

//The click wasnt in any of the rects
if (i != 0) {
    [super mouseDown:theEvent];
}}

Ответы [ 3 ]

0 голосов
/ 21 августа 2013

Я также хотел избежать пустого выделения в моем представлении коллекции.
То, как я это сделал, также делится на подклассы, но я переопределил -hitTest: вместо -mouseDown:, чтобы вернуть nil в случае, если клик не был по элементу:

-(NSView *)hitTest:(NSPoint)aPoint {
    // convert aPoint in self coordinate system
    NSPoint localPoint = [self convertPoint:aPoint fromView:[self superview]];
    // get the item count
    NSUInteger itemCount = [[self content] count];

    for(NSUInteger itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
        // test the point in each item frame
        NSRect itemFrame = [self frameForItemAtIndex:itemIndex];
        if(NSPointInRect(localPoint, itemFrame)) {
            return [[self itemAtIndex:itemIndex] view];
        }
    }

    // not on an item
    return nil;
}
0 голосов
/ 08 ноября 2013

Несмотря на то, что я опоздал на эту ветку, я подумал, что просто вмешаюсь, потому что у меня недавно была такая же проблема. Я обошел это используя следующую строку кода:

[_collectionView setValue:@NO forKey:@"avoidsEmptySelection"];

Есть одно предостережение: свойство avoidsEmptySelection не является частью официального API, хотя я думаю, что довольно безопасно предположить, что это тип свойства, который останется на некоторое время.

0 голосов
/ 16 января 2012

В итоге я просто создал подкласс NSCollectionView и переопределил метод - (void)mouseDown:(NSEvent *)theEvent. Я только потом отправил метод [super mouseDown: theEvent]; если клик был в одном из подпредставлений. Код:

- (void)mouseDown:(NSEvent *)theEvent {
NSPoint clickPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];

int i = 0;
for (NSView *view in self.subviews) {
    if (NSPointInRect(clickPoint, view.frame)) {
        //Click is in rect
        i = 1;
    }
}

//The click wasnt in any of the rects
if (i != 0) {
    [super mouseDown:theEvent];
}}
...