Question

I am writing a program that has a number of subclassed NSViews (Frame) with varying contents that can be dragged around by the mouse in their superview. All of the views contain one subview, called contentView, which in turn can contain a more complicated hierarchy.

If I have a non-editable NSTextField as the contentView the mouseDown: and mouseDragged: events get passed on to its superview without a problem and dragging works just fine.

mouseDown:    ---> [NSTextField] ---> [Frame]
mouseDragged: ---> [NSTextField] ---> [Frame]

If the contentView is a subclass of NSView that in turn contains a number of NSTextFields the mouseDragged: event is not passed on from the NSTextFields to the superview.

mouseDown:    ---> [NSTextField] ---> [subclassed NSView] ---> [Frame]
mouseDragged: ---> [NSTextField] -x-> 

The mouseDown: event is received by the frame. Clicking in the gaps between the NSTextFields and dragging the contentView directly works at well.

The NSTextFields are set up like this in the contentView:

NSTextField *textfield = [[NSTextField alloc] initWithFrame:rect];
[textfield setBordered:NO];
[textfield setSelectable:NO];
[textfield setEditable:NO];
[textfield setTextColor:[NSColor blackColor]];
[textfield setBackgroundColor:[NSColor clearColor]];
[textfield setDrawsBackground:NO];
[textfield setAlignment:NSRightTextAlignment];
[textfield setFont:[NSFont fontWithName:@"Helvetica" size:14]];
[self addSubview:textfield];
[textfield release];

I have tried adding a mouseDragged: method to both a subclassed NSTextField and the subclassed NSView, as well as leaving the method out. Neither made a difference. The problem also exists with other NSControls that are at the same subview level.

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

or

- (void)mouseDragged:(NSEvent *)theEvent
{
    [self.superview mouseDragged:theEvent];
}

At the moment this behaviour seems completely unintuitive to me. Is there something I am missing? (I am working with Xcode 4.6.2 on Mountain Lion.)

Was it helpful?

Solution 2

Okay, I found the answer. It had nothing to do with any NSTextFields cutting off any mouse events. When I clicked the NSView a routine was called to check whether the contents was still accurate. This would release all subviews and re-layout the whole view. That naturally cut off any dragging events from the mouseDown events of the same subview (which didn't exist anymore).

I solved the problem by checking whether the NSView was already activated for dragging, which I should have done in the first place. So, my error and none anybody else could have solved without my whole source code...

OTHER TIPS

NSTextView has special handling for the mouse. Not sure about NSTextField, but it might exhibit the same behaviour. For instance there's no mouseUp event. The mouseDown event enters a local loop (probably for dragging content). You could try to overwrite mouseDown in your class and call NSView's mouseDown to circumvent NSTextField's mouse down. See this SO question for how to do this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top