我最近审核了一年前发布的我的一个应用程序。
而且我看到现在它里面的NSCollectionView
已经失去了选择功能,例如SHIFT + Select现在它表现为CMD + Select而且我也无法用鼠标选择多个单元格(鼠标甚至没有绘制选择矩形)。
显然我想要这些功能。
我做了什么:
//NSCollectionView * _picturesGridView; //is my iVar
//In initialization I have set my _picturesGridView as follows
//Initializations etc are omitted -- (only the selection related code is here)
[_picturesGridView setSelectable:YES];
[_picturesGridView setAllowsMultipleSelection:YES];
问题:有没有简单的方法来取回此功能?我没有在文档中看到任何相关内容,我在互联网上找不到任何解决方案。
子问题:如果没有简单的方法可以实现这一点 - >我应该继续创建我自己的FancyPrefix##CollectionViewClass
并按照我的意愿重新实现这个功能 - 或者更好地检查现有的NSCollectionView
并强制它按照我的意愿行事?
子注意:好吧,如果我发现自己会重新实现它,它将是轻量级的,只会符合我自己的需要 - 我的意思是我不会模仿整个NSCollectionView
类。
P.S。 我可以通过单击选择一个项目我只能通过CMD +单击或SHIFT +单击选择多个项目,但最后一个表现与CMD +单击我不想要的那样。
对于鼠标选择矩形 - 我没有覆盖任何鼠标事件。目前尚不清楚为什么我没有这个功能: - |
答案 0 :(得分:0)
我从示例代码git@github.com:appcoda/PhotosApp.git
开始,整理了一个示例,所有更改都在ViewController.swift中。
我通过添加来跟踪移位是向上还是向下
var shiftDown = false
override func flagsChanged(with event: NSEvent) {
shiftDown = ((event.modifierFlags.rawValue >> 17) & 1) != 0
}
我添加了此实例变量以记住上一次选择
var lastIdx: IndexPath.Element?
然后,我在已经定义的collectionView(_:didSelectItemsAt)
中添加
let thisIdx = indexPaths.first?[1]
if shiftDown, let thisIdx = thisIdx, let lastIdx = lastIdx {
let minItem = min(thisIdx, lastIdx)
let maxItem = max(thisIdx, lastIdx)
var additionalPaths = Set<IndexPath>()
for i in minItem...maxItem {
additionalPaths.insert(IndexPath(item: i, section: 0))
}
collectionView.selectItems(at: additionalPaths, scrollPosition: [])
}
lastIdx = thisIdx
这只是一个开始。可能存在错误,尤其是在保存lastIdx
周围。
答案 1 :(得分:0)
每Apple的文档,shouldSelectItemsAtIndexPaths:
是事件仅被调用时与所述视图中的用户进行交互,而不是当所述选择是由自己的代码修改。因此,这种方法避免了使用didSelectItemsAt:
时可能发生的副作用。
它的工作原理如下:
NSCollectionView
实际上是一个名为CustomCollectionView
的具有属性@property (strong) NSIndexPath * _Nullable lastClickedIndexPath;
- (NSSet<NSIndexPath *> *)collectionView:(CustomCollectionView *)collectionView shouldDeselectItemsAtIndexPaths:(NSSet<NSIndexPath*> *)indexPaths
{
collectionView.lastClickedIndexPath = nil;
return indexPaths;
}
- (NSSet<NSIndexPath *> *)collectionView:(CustomCollectionView *)collectionView shouldSelectItemsAtIndexPaths:(NSSet<NSIndexPath*> *)indexPaths
{
if (indexPaths.count != 1) {
// If it's not a single cell selection, then we also don't want to remember the last click position
collectionView.lastClickedIndexPath = nil;
return indexPaths;
}
NSIndexPath *clickedIndexPath = indexPaths.anyObject; // now there is only one selected item
NSIndexPath *prevIndexPath = collectionView.lastClickedIndexPath;
collectionView.lastClickedIndexPath = clickedIndexPath; // remember last click
BOOL shiftKeyDown = (NSEvent.modifierFlags & NSEventModifierFlagShift) != 0;
if (NOT shiftKeyDown || prevIndexPath == nil) {
// not an extension click
return indexPaths;
}
NSMutableSet<NSIndexPath*> *newIndexPaths = [NSMutableSet set];
NSInteger startIndex = [prevIndexPath indexAtPosition:1];
NSInteger endIndex = [clickedIndexPath indexAtPosition:1];
if (startIndex > endIndex) {
// swap start and end position so that we can always count upwards
NSInteger tmp = endIndex;
endIndex = startIndex;
startIndex = tmp;
}
for (NSInteger index = startIndex; index <= endIndex; ++index) {
NSUInteger path[2] = {0, index};
[newIndexPaths addObject:[NSIndexPath indexPathWithIndexes:path length:2]];
}
return newIndexPaths;
}
此答案已被称为“社区Wiki”,以便任何人都可以改进此代码。如果您发现错误或可以使其表现更好,请这样做。