5
votes

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

3
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
I'm using NSTextView, not NSTextField. Yes, I get the same behavior as you do with textfields, but my application requires textviews.sam

3 Answers

6
votes

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];
}
1
votes

or, use a NSTextField, and then,

textfield.bezeled = NO;
textfield.drawsBackground = NO;
textfield.editable = NO;
textfield.selectable = YES;
[textfield setRefusesFirstResponder: YES];
0
votes

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