Пользовательские розетки в подклассе NSCollectionViewItem - PullRequest
2 голосов
/ 30 июля 2011

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

Теперь я переопределяю - (NSCollectionViewItem *)newItemForRepresentedObject:(id)object, потому что иногда мне нужно удалить этот NSImageView.

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

    CustomItem *theItem = (CustomItem *)[super newItemForRepresentedObject: object];

    ...

    if (I need to remove that NSImageView) {

        [[theItem additionalImageView] removeFromSuperview];

    }

    return theItem;

}

Так или иначе, дополнительныйImageView выглядит как (nil). Это в какой-то мере очевидно, потому что метод super будет возвращать NSCollectionViewItem по умолчанию, который не имеет пользовательского выхода.

Что лучше всего сделать прямо здесь? Я прочитал кое-что о методе copy и попробовал:

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

    CustomItem *theItem = [(CustomItem *)[super itemPrototype] copy]; // Here is the change

    ...

    if (I need to remove that NSImageView) {

        [[theItem additionalImageView] removeFromSuperview];

    }

    return theItem;

}

Но это не сработает. Итак, есть ли способ сохранить пользовательские выходы при использовании пользовательского NSCollectionViewItem?

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 2 ]

1 голос
/ 05 февраля 2013

Один из способов решения этой проблемы - создать 2 разных прототипа и привязать их к вашему контроллеру. Теперь, когда вы находитесь в newItemForRepresentedObject, вы можете установить view вашего NSCollectionViewItem с копией (используя протокол NSCoding) соответствующего прототипа в зависимости от объекта. Я использую NSCollectionViewItem Я получаю от супер.

Здесь Мой пример кода для показа редактора строковых или числовых атрибутов неизвестного NSManagedObject, NSManagedAttribute - это служебный класс, который я использую в качестве представленного объекта для представления моей коллекции и хранит информацию об атрибуте / отношения

- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object{
    NSManagedAttribute *attribute = object;
    NSCollectionViewItem *item =[super newItemForRepresentedObject:object];
    NSData * archivedView = nil;
    if (attribute.attributeType == NSInteger16AttributeType){
        archivedView = [NSKeyedArchiver archivedDataWithRootObject:self.controller.integerView];
    } else if (attribute.attributeType == NSStringAttributeType) {
        archivedView = [NSKeyedArchiver archivedDataWithRootObject:self.controller.stringView];
    }
    NSView * viewCopy = [NSKeyedUnarchiver unarchiveObjectWithData:archivedView];
    item.view = viewCopy;
    return item;
}

Это работает для меня: -)

1 голос
/ 12 сентября 2011

Проблема в том, что никто не будет создавать экземпляр изображения нового элемента. Копирование не будет работать, так как вам нужно два просмотра изображений, а не один.

Есть два способа справиться с этим:

  1. Вместо вызова реализации суперкласса newItemForRepresentedObject, используйте NSNib, чтобы создать экземпляр элемента самостоятельно (метод фабрики ниже). В вызове метода вы можете указать self в качестве владельца, и он подключит розетки для вас. Затем установите representedObject и поиграйте с изображением. Вот код для фабричного метода:

    // Load item view from CustomItem.nib
    // For consistent results, nib should contain exactly one NSCollectionViewItem.
    - (NSCollectionViewItem *)newCollectionViewItem {
        static NSNib *nib;
        if (!nib) nib = [[NSNib alloc] initWithNibNamed:@"CustomItem" bundle:nil];
    
        NSArray *nibObjects;
        if (![nib instantiateNibWithOwner:self topLevelObjects:&nibObjects]) return nil;
    
        for (id obj in nibObjects)
            if ([obj isKindOfClass:[NSCollectionViewItem class]])
                return (NSCollectionViewItem *)obj;
    
        return nil;
    }
    
  2. После того, как вы позвоните [super newItemForRepresentedObject:], проверьте, нужно ли сохранить представление изображения. Если вы это сделаете, создайте новый экземпляр NSImageView, установите его свойства и добавьте его в суперпредставление. Эта последняя часть звучит сложно. Может быть, кто-то, кто выбрал такой подход, предоставит некоторый код.

...