2

我觉得这是一项简单的任务,但我似乎无法让它发挥作用。我正在尝试使用带有自定义项目的 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;

}

无论如何,additionalImageView 似乎是(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 时保留自定义插座?

任何帮助将不胜感激。谢谢!

4

2 回答 2

1

问题是没有人会实例化新项目的图像视图。复制不起作用,因为您需要两个图像视图,而不是一个。

有两种方法可以处理这个问题:

  1. 与其调用 的超类实现newItemForRepresentedObjectNSNib不如自己实例化项目(下面的工厂方法)。在方法调用中,您可以指定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:],检查是否需要保留图像视图。如果你这样做了,实例化一个 new NSImageView,设置它的属性,并将它添加到 superview 中。最后一部分听起来很棘手。也许采用这种方法的人会提供一些代码。

于 2011-09-12T19:56:18.090 回答
1

解决问题的一种方法是创建 2 个不同的原型视图并将它们绑定到您的控制器。现在,当您在其中时,newItemForRepresentedObject您可以根据对象使用适当原型的副本(使用协议)设置view您的。我使用我从超级获得的。NSCollectionViewItemNSCodingNSCollectionViewItem

这里我的示例代码用于显示未知的字符串或数字属性编辑器NSManagedObjectNSManagedAttribute是一个实用程序类,我将其用作我的集合视图的表示对象并保留有关属性/关系的信息

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

它对我有用:-)

于 2013-02-05T02:11:13.240 回答