Как мне связать программно в подклассе представления моего NSCollectionView? - PullRequest
4 голосов
/ 31 июля 2009

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

Проблема, с которой я столкнулся, заключается в том, что, если я добавлю свой код инициализации для своих элементов управления в метод initWithCoder представления, а привязка в представлении awakeFromNib, привязка не будет подключена. Если я помещу инициализацию для своих элементов управления в awakeFromNib, при нажатии кнопки у меня не будет доступа к элементам управления в моем представлении (они равны нулю при печати с использованием 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

Ответы [ 3 ]

12 голосов
/ 27 августа 2009

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

Подкласс NSCollectionView и переопределение:

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

Надеюсь, это где-то рядом с тем, где вы должны быть ...

1 голос
/ 08 декабря 2013

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

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

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

...