gpt4 book ai didi

objective-c - 如何在 NSCollectionView 中正确显示当前选择?

转载 作者:行者123 更新时间:2023-12-03 17:31:13 24 4
gpt4 key购买 nike

我有一个正在显示一些图像的NSCollectionView。我已经实现了一个 NSCollectionViewDelegate 来告诉它应该选择和/或突出显示哪些项目。我正在使用库存 NSCollectionViewItem 来绘制图像及其名称。当用户选择一个项目时,我的委托(delegate)会收到有关突出显示状态更改的消息:

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

NSCollectionViewItemview 中,我执行以下操作:

- (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:。我在这里做错了什么吗?

我已经向 View 的 -drawRect: 方法添加了一些日志记录,即使我正在调用 -reloadItemsAtIndexPaths: -didChange* 方法中。为什么不?

我还注意到委托(delegate)的 -should/didDeselectItemsAtIndexPaths: 似乎从未被调用过,即使 -should/didSelectItemsAtIndexPaths: 确实被调用了。这是为什么?

最佳答案

问题原来是调用[collectionView reloadItemsAtIndexPaths:]。当您执行此操作时,它会删除现有的 NSCollectionViewItem 并创建一个新的(通过调用数据源的 collectionView:itemForRepresentedObjectAt:)。这会立即将新的 Collection View 项设置为未选择(或者更确切地说,它不会将其设置为选择)。发生这种情况时,它不会调用您的 should/didDeselect 方法,因为现有项目不再存在,并且不会选择新项目。

真正的解决方案是子类 NSCollectionViewItem 并重写 -setSelected: 来执行以下操作:

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

当 View 的 -drawRect: 方法被调用时,它会询问该项目是否已被选择并正确绘制。

因此,我可以毫无问题地从委托(delegate)中完全删除所有 should/did/select/Deselect 方法,而且一切都正常!

关于objective-c - 如何在 NSCollectionView 中正确显示当前选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41670851/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com