Как мне программно привязать подкласс представления моего NSCollectionView?

StackOverflow https://stackoverflow.com/questions/1210352

Вопрос

Я успешно создал NSCollectionView и добавил метку к прототипу представления в IB, привязанную к свойству представляемого мной объекта.Теперь я хочу программно создать NSButton и NSTextField с NSTextField, привязанным к свойству моего представленного объекта.Когда кнопка нажата, я хочу показать и скрыть NSTextField.

Проблема, с которой я столкнулся, заключается в том, что если я помещу свой код инициализации для своих элементов управления в метод initWithCoder представления, а привязку в AwakeFromNib представления, привязка не будет подключена.Если я помещу инициализацию своих элементов управления вawadFromNib, то при нажатии кнопки у меня не будет доступа к элементам управления в моем представлении (они будут иметь значение null при распечатке с помощью NSLog).

Насколько я могу судить, проблема может заключаться в том, что способ работы NSCollectionView заключается в том, что он создает экземпляр представления, а затем копирует его для того, сколько объектов находится в представлении коллекции.Как мне заставить кнопки инициализироваться и привязку для работы с копией прототипа?

Ниже приведен мой код инициализации и моя привязка в awakeFromNib для моего представления подкласса:

SubView.h

@interface SubView : NSView {
    NSButton *button;
    NSTextField *textField;
    IBOutlet NSCollectionViewItem *item; // Connected in IB to my NSCollectionViewItem
}

- (IBAction)buttonClicked:(id)sender;

@end

SubView.m

@implementation SubView

- (id)initWithCoder:(NSCoder *)decoder
{
    id view = [super initWithCoder:decoder];

    button = [[NSButton alloc] initWithFrame:NSMakeRect(50, 95, 100, 20)];
    [button setTitle:@"Begin Editing"];
    [button setTarget:self];
    [button setAction:@selector(buttonClicked:)];
    [self addSubview:button];

    textField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 100, 75)];
    [self addSubview:textField];

    return(view);
}

- (void)awakeFromNib
{   
        // Bind the textField to the representedObject's name property
        [textField bind:@"value" 
       toObject:item 
        withKeyPath:@"representedObject.name" 
        options:nil];
}

- (IBAction)buttonClicked:(id)sender
{
    [button setTitle:@"End Editing"];
    [textField setHidden:YES];
}

@end
Это было полезно?

Решение

Это похоже на то, что я только что сделал, так что, возможно, это то, что вам нужно.

Подкласс НСКоллектионвиев и переопределить:

- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object

В newItemForRepresentedObject:, получите элемент представления, затем добавьте элементы управления и любые программные привязки:

@implementation NSCollectionViewSubclass

- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object {

    // Allow the superclass to create or copy the collection view item
    NSSCollectionViewItem *newItem = [super newItemForRepresentedObject:object];

    // Get the new item's view so you can mess with it
    NSView *itemView = [newItem view];

    //
    // add your controls to the view here, bind, etc
    //

    return newItem;
}

@end

Надеюсь, это где-то близко к тому месту, где вам нужно быть...

Другие советы

-awakeFromNib не вызывается для представления для NSCollectionViewItem, если это представление находится в том же пере, что и NSCollectionView, но вызывается, если вы помещаете представление в отдельный перо.

  • Создайте пустой файл пера (BlahBlahCollectionViewItem.nib).
  • Вырежьте представление элемента коллекции из любого пера, в котором оно у вас есть.
  • Вставьте его в новый файл пера.
  • Измените класс его владельца на NSCollectionViewItem.
  • Подключите точку просмотра владельца к вновь вставленному виду.
  • Откройте файл пера, содержащий NSViewController.
  • Выберите связанный NSViewControllerItem.
  • Измените свойство Nib Name на имя нового наконечника.
  • Сохраните свой код -awakeFromNib

-awakeFromNib не вызывается для представлений, скопированных из прототипа NSCollectionViewItem.Введите код привязки initWithCoder: и с тобой должно быть все в порядке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top