2017-01-16 28 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方法,沒有任何問題,這一切都奏效!

相關問題