Double Click in NSCollectionView
Asked Answered
W

4

9

I'm trying to get my program to recognize a double click with an NSCollectionView. I've tried following this guide: http://www.springenwerk.com/2009/12/double-click-and-nscollectionview.html but when I do it, nothing happens because the delegate in IconViewBox is null:

The h file:

@interface IconViewBox : NSBox
{
    IBOutlet id delegate;
}
@end

The m file:

@implementation IconViewBox

-(void)mouseDown:(NSEvent *)theEvent {
    [super mouseDown:theEvent];

    // check for click count above one, which we assume means it's a double click
    if([theEvent clickCount] > 1) {
        NSLog(@"double click!");
        if(delegate && [delegate respondsToSelector:@selector(doubleClick:)]) {
            NSLog(@"Runs through here");
            [delegate performSelector:@selector(doubleClick:) withObject:self];
        }
    }
}

The second NSLog never gets printed because delegate is null. I've connected everything in my nib files and followed the instructions. Does anyone know why or an alternate why to do this?

Woodson answered 29/1, 2013 at 1:42 Comment(0)
C
9

You can capture multiple-clicks within your collection view item by subclassing the collection item's view.

  1. Subclass NSView and add a mouseDown: method to detect multiple-clicks
  2. Change the NSCollectionItem's view in the nib from NSView to MyCollectionView
  3. Implement collectionItemViewDoubleClick: in the associated NSWindowController

This works by having the NSView subclass detect the double-click and it pass up the responder chain. The first object in the responder chain to implement collectionItemViewDoubleClick: is called.

Typically, you should implement collectionItemViewDoubleClick: in the associated NSWindowController, but it can be in any object within the responder chain.

@interface MyCollectionView : NSView
/** Capture double-clicks and pass up responder chain */
-(void)mouseDown:(NSEvent *)theEvent;
@end

@implementation MyCollectionView

-(void)mouseDown:(NSEvent *)theEvent
{
    [super mouseDown:theEvent];

    if (theEvent.clickCount > 1)
    {
        [NSApplication.sharedApplication sendAction:@selector(collectionItemViewDoubleClick:) to:nil from:self];
    }
}

@end
Coley answered 19/9, 2013 at 7:37 Comment(0)
J
4

Another option is to override the NSCollectionViewItem and add an NSClickGestureRecognizer like such:

- (void)viewDidLoad
{
    NSClickGestureRecognizer *doubleClickGesture = 
            [[NSClickGestureRecognizer alloc] initWithTarget:self
                                                     action:@selector(onDoubleClick:)];
   [doubleClickGesture setNumberOfClicksRequired:2];
   // this should be the default, but without setting it, single clicks were delayed until the double click timed-out
   [doubleClickGesture setDelaysPrimaryMouseButtonEvents:FALSE];
   [self.view addGestureRecognizer:doubleClickGesture];
}

- (void)onDoubleClick:(NSGestureRecognizer *)sender
{
    // by sending the action to nil, it is passed through the first responder chain
    // to the first object that implements collectionItemViewDoubleClick:
    [NSApp sendAction:@selector(collectionItemViewDoubleClick:) to:nil from:self];
}
Jewelfish answered 8/3, 2019 at 1:14 Comment(0)
T
0

What you said notwithstanding, you need to be sure you followed step four in the tutorial:

4. Open IconViewPrototype.xib in IB and connect the View's delegate outlet with "File's Owner":

That should do ya, provided you did follow the rest of the steps.

Terminator answered 29/1, 2013 at 4:10 Comment(1)
I do connect the IconViewBox's delegate to an IconCollectionViewItem although it's not File's Owner because I'm trying to add it to my own project, which is set up differently than the example they have.Woodson
M
0

If you are listening for double click, you can also create a subclass of NSView and override its rightMouseDown method:

class MyView: NSView {
  override func rightMouseDown(with event: NSEvent) {
    print("Right mouse down")
  }
}
Mccutchen answered 26/6, 2024 at 16:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.