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

내가보기에 문제는 하이라이트 또는 선택을 그리는 것이 실행되는 것 같습니다. 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:를 오버라이드 (override)으로 밝혀졌다 : 그것은 선택하고 적절하게 그립니다 않다면

뷰의 -drawRect: 메소드가 호출되는
- (void)setSelected:(BOOL)selected 
{ 
    [super setSelected:selected]; 
    [self.view setNeedsDisplay:YES]; 
} 

, 그것은 항목을 요청합니다.

따라서 위의 모든 should/did/select/Deselect 메서드를 아무 문제없이 완전히 제거 할 수 있습니다.

관련 문제