2017-01-16 31 views
0

我有一个NSCollectionView显示一些图像。我实施了一个NSCollectionViewDelegate来告诉它应该选择和/或突出显示哪些项目。我正在使用库存NSCollectionViewItem来绘制图像及其名称。当用户选择一个项目,我代表得到消息关于高亮度状态的变化:如何在NSCollectionView中正确显示当前选择?

- (void)collectionView:(NSCollectionView *)collectionView 
didChangeItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths 
     toHighlightState:(NSCollectionViewItemHighlightState)highlightState 
{ 
    [collectionView reloadItemsAtIndexPaths:indexPaths]; 
} 

我为didSelect/didDeselect做类似的事情:

- (void)collectionView:(NSCollectionView *)collectionView 
didSelectItemsAtIndexPaths:(nonnull NSSet<NSIndexPath *> *)indexPaths 
{ 
    [collectionView reloadItemsAtIndexPaths:indexPaths]; 
} 

NSCollectionViewItem小号view,我做的以下:

- (void)drawRect:(NSRect)dirtyRect { 
    [super drawRect:dirtyRect]; 

    NSColor* bgColor   = [[self window] backgroundColor]; 
    NSColor* highlightColor = [NSColor selectedControlColor]; 

    NSRect frame = [self bounds]; 
    NSCollectionViewItemHighlightState hlState  = [collectionViewItem highlightState]; 
    BOOL        selected = [collectionViewItem isSelected]; 
    if ((hlState == NSCollectionViewItemHighlightForSelection) || (selected)) 
    { 
     [highlightColor setFill]; 
    } 
    else 
    { 
     [bgColor setFill]; 
    } 
    [NSBezierPath fillRect:frame]; 
} 

我看到的问题是绘制突出显示或选择似乎是跑DOM。当它绘制选择时,它几乎总是在用户实际选择的项目上(尽管由于某种原因通常会遗留最后一个项目)。偶尔,它会选择用户没有点击或拖动的其他项目。但是,通常情况下,它不会画出来。

我已添加打印以确认它正在呼叫-didChangeItemsAtIndexPaths:toHighlightState:-didSelectItemsAtIndexPaths:。有什么我在这里做错了吗?

我已经添加了一些记录到视图的-drawRect:方法,并没有出现有愈演愈烈呼吁所有过渡,即使我打电话的-didChange*方法-reloadItemsAtIndexPaths:。为什么不?

我也注意到,尽管-should/didSelectItemsAtIndexPaths:确实被调用,但代理的-should/didDeselectItemsAtIndexPaths:似乎并没有被调用过。这是为什么?

+0

试试这个链接可能会帮助你http://stackoverflow.com/questions/2541572/selection-highlight-in-nscollectionview?rq=1 –

回答

1

问题竟然是要求[collectionView reloadItemsAtIndexPaths:]。当你这样做时,它将删除现有的NSCollectionViewItem并创建一个新的(通过调用您的数据源的collectionView:itemForRepresentedObjectAt:)。这会立即将新的集合视图项目设置为未选中状态(或者不会将其设置为选中状态)。发生这种情况时,它不会调用您的should/didDeselect方法,因为现有项目不再存在,并且未选中新项目。

真正的解决方案竟然是子类NSCollectionViewItem并覆盖-setSelected:做到以下几点:

- (void)setSelected:(BOOL)selected 
{ 
    [super setSelected:selected]; 
    [self.view setNeedsDisplay:YES]; 
} 

当视图的-drawRect:方法被调用,它要求的项目,如果它的选择,并适当借鉴。

因此,我可以完全删除委托中的所有should/did/select/Deselect方法,没有任何问题,这一切都奏效!

相关问题