1

Does anyone know a way to detect when an NSScrollView is scrolled by user input, and only user input)?

The reason I want to do this is because I have a NSScrollView with a contentView that is continuously increasing it's width. I want the NSScrollView to 'lock' onto the right hand end of the contentView (i.e. track it) if the user scrolls to the right hand end of the contentView and I want the 'lock' to be released when the user (and only the scrolls) scrolls aways from the right hand end.

The closest I had to getting to this to work was by observing the NSViewBoundsDidChangeNotification and changing a 'lock' variable, as shown here:

- (void)drawRect:(NSRect)dirtyRect
{
(...)
    if (lockToEnd) {
        NSLog(@"xAxisView at end");
        NSPoint newScrollOrigin;
        newScrollOrigin.y = 0;
        newScrollOrigin.x = [self frame].size.width - [[self enclosingScrollView] bounds].size.width;
        [self scrollPoint:newScrollOrigin];
    }
}

-(void)SWXAxisViewDidScroll:(NSNotification *)note{
    NSLog(@"XAxisDidScroll: %@",note);
    if ([[[self enclosingScrollView] horizontalScroller] floatValue] > 0.97){
        lockToEnd = YES;
    } else {
        lockToEnd = NO;
    }
}

However, this was not appropriate because an NSViewBoundsDidChangeNotification is sent anytime the bounds are changed, and thus when the bounds of the contentView increase, the NSScroller reduces it's floatValue and my observing method is called. EVen if I set the NSScroller's floatValue to 1.0, it is reset to 0.0 when the bounds.size.width of the contentView first exceeds the bounds.size.width of the NSScrollView. Thus, I can't tell if the NSViewBoundsDidChangeNotification was sent because the user scrolled or because the contentView got wider.

I have considered subclassing NSScroller and using the mouseDown: and mouseDragged: methods to track user input and update my lock variable. However, my concern is that these methods will not be called if the user swipes their trackpad to scroll. Another smaller concern, which I think is probably unfounded, is that it might break the NSScrollView<->NSScroller relationship and I would have to re-implement a lot of scrolling features.

Have I missed a simpler way to do this? It seems like I should be able to do this because documents do it all the time? Are my concerns about subclassing NSScroller valid?

Justin Boo
  • 10,132
  • 8
  • 50
  • 71
  • Of I realised just after posting that calling [super mouseDown:...] and [super mouseDragged:..] would probably solve and concerns I had about breaking the NSScroller<->NSScrollView relationship. –  Mar 02 '12 at 05:43
  • Except I was wrong. Sending a mouseDown or mouseDragged message to super cancels out the rest of the method, whether you call it at the end or the start. Not sending these messages breaks the NSScroller. –  Mar 02 '12 at 08:14
  • Is it a problem with subclassing an NSControl? –  Mar 02 '12 at 08:53

0 Answers0