26

It seems like NSSlider in Cocoa does not provide a delegate to receive an event like Value Changed for a UISlider.

How can I get the value of an NSSlider continuously and display it in an NSTextField, for example?

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
meddlesome
  • 551
  • 7
  • 20

3 Answers3

49

You need to research Cocoa's Target/Action mechanism. This is a basic Cocoa concept you'll need to understand. The slider (and any other control) can be given a target (some controller object) and an action (the method to call against that controller object).

The action is fired when the user stops dragging by default. Check the slider's Continuous property in Interface Builder to cause it to trigger the action as you're sliding it.

Joshua Nozzi
  • 60,946
  • 14
  • 140
  • 135
  • 11
    Check a Continuous property for NSSlider is totally works, Thanks ! – meddlesome Jul 01 '11 at 22:54
  • 1
    @meddlesome `continuous` property is what I was looking for. Thank you! – derpoliuk Jun 04 '15 at 13:11
  • 1
    I wish there were a way to have separate action methods for the `continuous` value and after they let go of the slider. – Clifton Labrum Aug 30 '18 at 18:07
  • 1
    @CliftonLabrum You could use `NSApplication.currentEvent` in your existing action function to check the `event.type` mask for the presence of `NSEvent.EventType.leftMouseDragged` and differentiate your action’s behavior based on this. If it was called as a result of a drag, it was a “continuous” adjustment; if not, it was a single direct click or a mouse-up letting-go-of the slider at its final position. – Joshua Nozzi Aug 30 '18 at 18:51
  • Thanks! I decided to just set the slider to `continuous` and then set a timer so that if they haven't dragged it for a couple seconds, I consider the value ready to save to my database. – Clifton Labrum Aug 30 '18 at 18:56
  • 1
    @CliftonLabrum Certainly an approach, though it makes me nervous about non-main-queue event syncing. Without knowing more, it’s impossible to say whether you should expect trouble but it’s something to evaluate and keep in mind. – Joshua Nozzi Aug 30 '18 at 19:00
  • Your Cocoa reference is out of date (does not exist). – qwerty_so Aug 31 '18 at 06:37
  • Thanks. From a "The page you’re looking for can’t be found." it's a bit hard to fix th broken link. – qwerty_so Sep 01 '18 at 07:19
  • It’s hard to keep years-old links up to date, but Google sure finds it as the first hit for “cocoa target action.” – Joshua Nozzi May 12 '21 at 00:35
2

One advantage of using the timer approach is that it works for the case of using the keyboard rather than the mouse to adjust the slider. If the user has "Full Keyboard Access" turned on in System Preferences, they can use the Tab key to give the slider focus. They can then hold down an arrow key so that autorepeat kicks in, whereupon you have a similar situation to dragging with the mouse: the target/action is firing repeatedly, and you want to wait for a moment of calm before saving to the database.

You do need to be careful not to delete your NSTimer prematurely. For example, if the user quits the app during those couple of seconds you probably want to "flush" the slider value to the database before terminating the process.

Andy Lee
  • 21
  • 2
2

Programmatical solution based on the answer of Joshua Nozzi:

Swift

slider.isContinuous = true

Objective-C

slider.continuous = YES;
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223