5

I have a view-based single-column NSTableView. Inside my NSTableCellView subclass I have an NSTextView which is selectable, but not editable.

When the user clicks on the NSTableCellView directly, the row highlights properly. But when the user clicks on the NSTextView inside that NSTableCellView, the row does not highlight.

How do I get the click on the NSTextView to pass to the NSTableCellView so that the row highlights?

Class hierarchy looks like: NSScrollView > NSTableView > NSTableColumn > NSTableCellView > NSTextView

sam
  • 3,399
  • 4
  • 36
  • 51
  • I can't duplicate what you're seeing. When I add a text field to a view based cell, clicking on it selects the row not the text field (I have to click again to get that to happen). Do you have it bound to anything, or are you using a data source? – rdelmar Apr 18 '12 at 03:24
  • I'm using NSTextView, not NSTextField. Yes, I get the same behavior as you do with textfields, but my application requires textviews. – sam Apr 25 '12 at 01:37

3 Answers3

6

Here's what I ended up doing. I made a subclass of NSTextView and overrode mouseDown: as follows...

- (void)mouseDown:(NSEvent *)theEvent
{
    // Notify delegate that this text view was clicked and then
    // handled the click natively as well.
    [[self myTextViewDelegate] didClickMyTextView:self];
    [super mouseDown:theEvent];
}

I'm reusing NSTextView's standard delegate...

- (id<MyTextViewDelegate>)myTextViewDelegate
{
    // See the following for info on formal protocols:
    // stackoverflow.com/questions/4635845/how-to-add-a-method-to-an-existing-protocol-in-cocoa
    if ([self.delegate conformsToProtocol:@protocol(MyTextViewDelegate)]) {
        return (id<MyTextViewDelegate>)self.delegate;
    }
    return nil;
}

And in the header...

@protocol MyTextViewDelegate <NSTextViewDelegate>
- (void)didClickMyTextView:(id)sender;
@end

In the delegate, I implement didClickMyTextView: to select the row.

- (void)didClickMyTextView:(id)sender
{
    // User clicked a text view. Select its underlying row.
    [self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:[self.tableView rowForView:sender]] byExtendingSelection:NO];
}
sam
  • 3,399
  • 4
  • 36
  • 51
0

I think you have essentially the same problem I had here: pass event on. See the accepted answer.

Following the same pattern, you would subclass NSTextView and override - (void)mouseUp:(NSEvent *)theEvent to pass the event on to the superView, which I'm assuming is the tableView:

- (void)mouseUp:(NSEvent *)theEvent {
    [superView mouseUp:theEvent]; 
}
Community
  • 1
  • 1
Wienke
  • 3,723
  • 27
  • 40
  • 1
    No luck. Overriding mouseUp: and sending the event to the superView doesn't seem to do anything. Then I tried overriding mouseDown: and sending the event to the superView. That does select the row, but then I lose the ability to select text (basically the textview's mouse functionality). I did resolve this as described in my answer and it's not too different from what you had in mind. – sam Apr 25 '12 at 01:43
0

or, use a NSTextField, and then,

textfield.bezeled = NO;
textfield.drawsBackground = NO;
textfield.editable = NO;
textfield.selectable = YES;
[textfield setRefusesFirstResponder: YES];
gene tsai
  • 83
  • 2