IPhone: how to determine the end of a drag slider?

How to detect the event when the user has finished dragging the slider pointer?

+79
ios iphone ios4 ios5 uislider
Feb 22 2018-12-12T00
source share
15 answers

If you do not need data between drag and drop, you should simply set:

[mySlider setContinuous: NO]; 

This way you get the valueChanged event only when the user stops moving the slider.

+148
Feb 22 '12 at 8:08
source share

You can add an action that takes two parameters, sender and event, for UIControlEventValueChanged:

 [slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged] 

Then check the phase of the touch object in your handler:

 - (void)onSliderValChanged:(UISlider*)slider forEvent:(UIEvent*)event { UITouch *touchEvent = [[event allTouches] anyObject]; switch (touchEvent.phase) { case UITouchPhaseBegan: // handle drag began break; case UITouchPhaseMoved: // handle drag moved break; case UITouchPhaseEnded: // handle drag ended break; default: break; } } 

Swift 4 and 5

 slider.addTarget(self, action: #selector(onSliderValChanged(slider:event:)), for: .valueChanged) 
 @objc func onSliderValChanged(slider: UISlider, event: UIEvent) { if let touchEvent = event.allTouches?.first { switch touchEvent.phase { case .began: // handle drag began case .moved: // handle drag moved case .ended: // handle drag ended default: break } } } 

Note that in Interface Builder, when adding an action, you can also add sender and event parameters to the action.

+85
Aug 09 '16 at 3:18
source share

I use the “Touch Up Inside” and “Touch out outside” notifications.

Interface Constructor:

Connect both notifications in the interface builder to your receiving method. The method may look like this:

 - (IBAction)lengthSliderDidEndSliding:(id)sender { NSLog(@"Slider did end sliding... Do your stuff here"); } 

In code:

If you want to program it programmatically, you will have something like this in your WillAppear view (or wherever it suits you):

 [_mySlider addTarget:self action:@selector(sliderDidEndSliding:) forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)]; 

The reception method will look like this:

 - (void)sliderDidEndSliding:(NSNotification *)notification { NSLog(@"Slider did end sliding... Do your stuff here"); } 
+69
Mar 03 '12 at 7:01
source share

Since UISlider is a subclass of UIControl , you can set a goal and action for your UIControlEventTouchUpInside .

If you want to do this in code, it looks like this:

 [self.slider addTarget:self action:@selector(dragEndedForSlider:) forControlEvents:UIControlEventTouchUpInside]; 

This message will send you a dragEndedForSlider: message when you click.

If you want to do this at your tip, you can click its slider to open its connections menu, and then drag it from the Touch Up Inside socket to the target.

You must also add a target and action for UIControlEventTouchUpOutside and for UIControlEventTouchCancel .

+16
Feb 22 2018-12-22T00:
source share

Swift 5 and Swift 4

  1. Add a target for touchUpInside and touchUpOutside . You can do this either programmatically or from the storyboard. Here's how you do it programmatically

     slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside]) 
  2. Write your function to handle the end of the slider

     func sliderDidEndSliding() { print("end sliding") } 
+14
May 10 '17 at 15:49
source share

You can use:

 - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents 

to detect when touchDown and touchUp events occur in UISlider

+10
Feb 22 2018-12-12T00:
source share

It seems to me that you need a control event UIControlEventTouchUpInside .

+7
Feb 22 '12 at 7:03
source share

Connect Touch Up Inside and Value Changed

enter image description here

+4
Sep 11 '16 at 8:39
source share

Swift 3 answer

I had the same problem, and in the end I succeeded, so maybe this will help someone. Connect your_Slider to the “Value Changed” in the storyboard, and when the slider moves, “Slider Touched” fires, and if you release “Slider Released”.

 @IBAction func your_Slider(_ sender: UISlider) { if (yourSlider.isTracking) { print("Slider Touched") } else { print("Slider Released") } } 
+4
Mar 13 '17 at 17:43 on
source share

Swift 3.1

Sometimes you need to have the drag and drop events of the slider run continuously, but have the ability to execute different code depending on whether the slider is being dragged or just dragged.

To do this, I extended Andy's answer above, which uses the sla isTracking property. I needed to write two states: sliderHasFinishedTracking and sliderLastStoredValue .

My code is correct:

  • does not start an action when starting drag

  • triggers an action if the user only pushes the slider with one click (this means that isTracking remains false )




 class SliderExample: UIViewController { var slider: UISlider = UISlider() var sliderHasFinishedTracking: Bool = true var sliderLastStoredValue: Float! override func loadView() { super.loadView() slider.minimumValue = 100.0 slider.maximumValue = 200.0 slider.isContinuous = true slider.value = 100.0 self.sliderLastStoredValue = slider.value slider.addTarget(self, action: #selector(respondToSlideEvents), for: .valueChanged) // add your slider to the view however you like } func respondToSlideEvents(sender: UISlider) { let currentValue: Float = Float(sender.value) print("Event fired. Current value for slider: \(currentValue)%.") if(slider.isTracking) { self.sliderHasFinishedTracking = false print("Action while the slider is being dragged ⏳") } else { if(self.sliderHasFinishedTracking && currentValue == self.sliderLastStoredValue){ print("Slider has finished tracking and its value hasn't changed, " + "yet event was fired anyway. 🤷") // No need to take action. } else { self.sliderHasFinishedTracking = true print("Action upon slider drag/tap finishing ⌛️") } } self.sliderLastStoredValue = currentValue } } 
+4
May 13 '17 at 12:33
source share

In Swift 4 you can use this function

1 Frist step: - Adding a target to the slider

 self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside])) 

2 Second step: - Create a function

 @objc func sliderDidEndSliding(notification: NSNotification) { print("Hello-->\(distanceSlider.value)") } 
+4
Dec 22 '17 at 9:20
source share

I have had a similar problem lately. Here is what I did in Swift:

  theSlider.continuous = false; 

The code that contains this continuous value reads:

 public var continuous: Bool // if set, value change events are generated // any time the value changes due to dragging. default = YES 

The default value is YES (true). Setting it to false does what you want.

+1
Mar 19 '16 at 23:02
source share

Perhaps you should add a target for the events UIControlEventTouchUpInside, UIControlEventTouchUpOutside, UIControlEventTouchCancel.

I met the same problem before because I am not adding a target for the UIControlEventTouchCancel event.

+1
Dec 21 '17 at 8:32
source share

try it

 customSlider.minimumValue = 0.0; customSlider.maximumValue = 10.0; [customSlider addTarget:self action:@selector(changeSlider:) forControlEvents:UIControlEventValueChanged]; -(void)changeSlider:(id)sender{ UISlider *slider=(UISlider *)sender; float sliderValue=(float)(slider.value ); NSLog(@"sliderValue = %f",sliderValue); } 
0
Feb 22 2018-12-22T00:
source share

RxSwift:

 self.slider.rx.controlEvent([.touchUpInside, .touchUpOutside]) .bind(to: self.viewModel.endSlidingSlider) .disposed(by: self.disposeBag) 
0
Sep 03 '19 at 12:09 on
source share



All Articles