Search code examples
objective-ccocoansslider

Determine when NSSlider knob is 'let go' in continuous mode


I'm using an NSSlider control, and I've configured it to use continuous mode so that I can continually update an NSTextField with the current value of the slider while the user is sliding it around. The issue I have is that I don't want to 'commit' the value until the user lets go of the knob, i.e I don't want my application to take account of the value unless the user lets go of the slider to signify it's at the desired value. At the moment, I have no way of knowing when that's the case; the action method is just getting called continuously with no indication of when the slider has been released.

If possible, I need a solution which will cover edge cases such as the user interacting the with slider with the keyboard or accessibility tools (if there is such a thing). I'd started to look into using mouse events, but it didn't seem like an optimum solution for the reasons I've just outlined.


Solution

  • This works for me (and is easier than subclassing NSSlider):

    - (IBAction)sizeSliderValueChanged:(id)sender {
        NSEvent *event = [[NSApplication sharedApplication] currentEvent];
        BOOL startingDrag = event.type == NSLeftMouseDown;
        BOOL endingDrag = event.type == NSLeftMouseUp;
        BOOL dragging = event.type == NSLeftMouseDragged;
    
        NSAssert(startingDrag || endingDrag || dragging, @"unexpected event type caused slider change: %@", event);
    
        if (startingDrag) {
            NSLog(@"slider value started changing");
            // do whatever needs to be done when the slider starts changing
        }
    
        // do whatever needs to be done for "uncommitted" changes
        NSLog(@"slider value: %f", [sender doubleValue]);
    
        if (endingDrag) {
            NSLog(@"slider value stopped changing");
            // do whatever needs to be done when the slider stops changing
        }
    }