2017-01-16 10 views
0

NSCollectionView私はいくつかの画像を表示しています。私はNSCollectionViewDelegateを実装して、どの項目を選択して強調表示するかを指示しました。画像とその名前を描画するために在庫NSCollectionViewItemを使用しています。ユーザーが項目を選択すると、私のデリゲートは、ハイライト状態の変更に関するメッセージを取得します。NSCollectionViewに現在のセレクションを正しく表示する方法は?

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

私はdidSelect/didDeselectについても同様のことを実行します。NSCollectionViewItemview

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

を、私がやります以下:

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

私が見ている問題は、ハイライトや選択を描画することが実行されているようだドーム。選択を描画するときは、ほとんどの場合、ユーザーが実際に選択したアイテムになります(何らかの理由で最後のアイテムから離れることが多い)。ユーザーがクリックしたりドラッグしたりしなかった別の項目が選択されることがあります。しばしば、しかし、それは描画しません。

プリントを追加して、-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が削除され、新しいものが作成されます(データソースのを呼び出すことによって)。これにより、すぐに新しいコレクションビューアイテムが選択されないように設定されます(または、選択されないように設定されます)。その場合、既存の項目がもう存在しないため、新しい項目が選択されていないため、should/didDeselectのメソッドは呼び出されません。

真の解決策は、NSCollectionViewItemをサブクラス化し、次の操作を実行するために-setSelected:を上書きすることが判明:ビューの-drawRect:メソッドが呼び出されるとき

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

、それが選択されている場合に、アイテムを要求し、適切に描画します。

したがって、私はshould/did/select/Deselectのメソッドをデリゲートから完全に削除しても問題ありませんでした。

関連する問題