Detecting touches on a UISlider?
Asked Answered
S

3

15

I have a UISlider on screen, and I need to be able to detect when the user stops touching it. (so I can fade some elements away).

I have tried using:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

but this did not work when ending touches on a slider.

Sponger answered 10/6, 2012 at 18:18 Comment(2)
Why not use a target+action with UIControlEventTouchUpInside or UIControlEventTouchUpOutside?Mummify
This is a great suggestion! I wasn't aware you could use UIControlEventTouchUpInside on a UISlider, but it works! :)Sponger
M
21

You can detect when a touch ends using two control events; try

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

or

[slider addTarget:self action:@selector(touchEnded:) 
                       forControlEvents:UIControlEventTouchUpOutside];

If you want to detect both types of the touchesEnd event, use

[slider addTarget:self action:@selector(touchEnded:) 
   forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
Mummify answered 10/6, 2012 at 18:46 Comment(0)
J
6

Instead of using touchesEnded: (which shouldn't be used for this purpose anyway), attach an action to the UISlider's UIControlEventValueChanged event and set the continuous property of the UISlider to NO, so the event will fire when the user finishes selecting a value.

mySlider.continuous = NO;
[mySlider addTarget:self
          action:@selector(myMethodThatFadesObjects) 
          forControlEvents:UIControlEventValueChanged];
Jauregui answered 10/6, 2012 at 18:25 Comment(2)
It's a nice idea that works, but I was already using UIControlEventValueChanged to get live updates on where the UISlider was, so I couldn't do that if I set continuous to no.Sponger
So you want to get the value in realtime, but only apply that value when the user stops touching it? That should have been stated in your question.Jauregui
S
6

I couldn't get anything to capture both the start and end of the touches, but upon RTFD-ing, I came up with something that will do both.

  @IBAction func sliderAction(_ sender: UISlider, forEvent event: UIEvent) {

    if let touchEvent = event.allTouches?.first {
      switch touchEvent.phase {
      case .began:
        print("touches began")
        sliderTouchBegan()
      case .ended:
        print("touches ended")
        sliderTouchEnded()
      default:
        delegate?.sliderValueUpdated(sender.value)
      }
    }
  }

sliderTouchBegan() and sliderTouchEnded() are just methods I wrote that handle animations when the touch begins and when it ends. If it's not a begin or end, it's a default and the slider value updates.

Stateroom answered 5/7, 2018 at 21:21 Comment(2)
Which control event type are u using for the sliderAction() ? Is it UIControlEvents.allTouchEvents?Brenn
@Hamed When you drag out the connection from the storyboard, make it an action and under arguments, make sure you specify sender AND (emphasis mine) event.Stateroom

© 2022 - 2024 — McMap. All rights reserved.