У меня есть рабочий 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




