3

我已经在可可应用程序中设置了一个NSCollectionView。我已经对集合视图进行了子类化,以便在它选择/取消选择其中一个视图时NSCollectionViewItem向我发送自定义。NSNotification发布此通知时,我注册以在我的控制器对象中接收通知。在这个方法中,我告诉刚刚被选中的视图它被选中并告诉它重绘,这使得它自己着色为灰色。

子类NSCollectionViewItem

-(void)setSelected:(BOOL)flag {
[super setSelected:flag];

[[NSNotificationCenter defaultCenter] postNotificationName:@"ASCollectionViewItemSetSelected" 
                                                    object:nil 
                                                  userInfo:[NSDictionary dictionaryWithObjectsAndKeys:(ASListView *)self.view, @"view", 
                                                            [NSNumber numberWithBool:flag], @"flag", nil]];}

控制器类(在-(void)awakeFromNib方法中):

//Register for selection changed notification
[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(selectionChanged:) 
                                             name:@"ASCollectionViewItemSetSelected" 
                                           object:nil];

-(void)selectionChanged:(NSNotification *)notification方法:

- (void)selectionChanged:(NSNotification *)notification {
// * * Must get the selected item and set its properties accordingly

//Get the flag
NSNumber *flagNumber = [notification.userInfo objectForKey:@"flag"];
BOOL flag = flagNumber.boolValue;

//Get the view
ASListView *listView = [notification.userInfo objectForKey:@"view"];

//Set the view's selected property
[listView setIsSelected:flag];
[listView setNeedsDisplay:YES];

//Log for testing
NSLog(@"SelectionChanged to: %d on view: %@", flag, listView);}

包含此代码的应用程序要求在任何时候集合视图中都没有空选择。这就是我遇到问题的地方。我尝试检查视图的选择何时更改,如果没有选择则重新选择它,并使用NSCollectionView's手动选择视图

-(void)setSelectionIndexes:(NSIndexSet *)indexes

但是总有一种情况会导致集合视图中出现空选择。

所以我想知道是否有一种更简单的方法可以防止出现空选择NSCollectionView?我在界面生成器中看不到复选框。

提前致谢!

更新

我最终只是继承了我的NSCollectionView,并覆盖了该- (void)mouseDown:(NSEvent *)theEvent方法。[super mouseDown:theEvent];如果单击位于其中一个子视图中,我才发送该方法。代码:

- (void)mouseDown:(NSEvent *)theEvent {
NSPoint clickPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];

int i = 0;
for (NSView *view in self.subviews) {
    if (NSPointInRect(clickPoint, view.frame)) {
        //Click is in rect
        i = 1;
    }
}

//The click wasnt in any of the rects
if (i != 0) {
    [super mouseDown:theEvent];
}}
4

3 回答 3

0

我最终只是继承了我的 NSCollectionView,并覆盖了该- (void)mouseDown:(NSEvent *)theEvent方法。然后我才发送方法 [super mouseDown:theEvent]; 如果点击在其中一个子视图中。代码:

- (void)mouseDown:(NSEvent *)theEvent {
NSPoint clickPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];

int i = 0;
for (NSView *view in self.subviews) {
    if (NSPointInRect(clickPoint, view.frame)) {
        //Click is in rect
        i = 1;
    }
}

//The click wasnt in any of the rects
if (i != 0) {
    [super mouseDown:theEvent];
}}
于 2012-01-16T14:07:25.870 回答
0

我还想避免在我的收藏视图中出现空选择。
我这样做的方式也是通过子类化,但如果点击不在项目上,我会覆盖-hitTest:而不是-mouseDown:返回:nil

-(NSView *)hitTest:(NSPoint)aPoint {
    // convert aPoint in self coordinate system
    NSPoint localPoint = [self convertPoint:aPoint fromView:[self superview]];
    // get the item count
    NSUInteger itemCount = [[self content] count];

    for(NSUInteger itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
        // test the point in each item frame
        NSRect itemFrame = [self frameForItemAtIndex:itemIndex];
        if(NSPointInRect(localPoint, itemFrame)) {
            return [[self itemAtIndex:itemIndex] view];
        }
    }

    // not on an item
    return nil;
}
于 2013-08-21T08:56:05.173 回答
0

虽然我迟到了这个帖子,但我想我只是插话,因为我最近遇到了同样的问题。我使用以下代码行解决了这个问题:

[_collectionView setValue:@NO forKey:@"avoidsEmptySelection"];

有一个警告:该avoidsEmptySelection属性不是官方 API 的一部分,尽管我认为可以很安全地假设它是会存在一段时间的属性类型。

于 2013-11-08T10:42:26.997 回答