У меня есть рабочий NSCollectionView
с одним незначительным, но критическим исключением. Получение и выделение выделенного элемента в коллекции.
У меня все это работало до Snow Leopard, но что-то, похоже, изменилось, и я не могу наложить на него свой палец, поэтому я вернул обратно NSCollectionView
к базовому тесту и последовал за документацией Apple для создания NSCollectionView здесь:
Вид коллекций отлично работает после краткого руководства по началу работы. Однако в этом руководстве не обсуждается выбор, отличный от "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
и в отличие от большинства представлений пользовательского интерфейса Cocoa, по-видимому, нет выделенного выделения по умолчанию.
Итак, моя проблема действительно сводится к связанной проблеме, но два разных вопроса.
- Как я могу выделить элемент?
- Как показать выделение элемента?
NSCollectionView
Руководство по программированию, по-видимому, мало и далеко, и большинство поисков через Google, похоже, вытягивают реализации до снега Leopard или используют представление в отдельном файле XIB.
Для последнего (отдельный XIB файл для представления) я не понимаю, почему это должно быть предпосылкой, иначе я бы предположил, что Apple не включила бы представление в тот же пакет, что и элемент представления коллекции.
Я знаю, что это будет вопрос "не видно дерева для деревьев", поэтому я готов к "дох!". момент.
Как обычно, все и вся помощь очень ценятся.
Обновление 1
ОК, поэтому я решил найти выбранный элемент (ы), но еще не определил выделение. Для интересующихся при выборе выбранных элементов (при условии, что вы следуете руководству Apple):
В контроллере (в моем тестовом примере App Delegate) я добавил следующее:
В 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
Взял совет по макатомии, но все еще имел проблему. Публикация соответствующих методов класса, чтобы увидеть, где я ошибся.
MyView.h
#import <Cocoa/Cocoa.h>
@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 <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