How to detect the event when the user has ended the drag of a slider pointer?
问题:
回答1:
If you don't need any data inbetween drag, than you should simply set:
[mySlider setContinuous: NO];
This way you will receive valueChanged
event only when the user stops moving the slider.
回答2:
I use the "Touch Up Inside" and "Touch up outside" notifications.
Interface Builder:
Connect both notifications in the Interface Builder to your receiving method. The method could look like this:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
In code:
If you want to wire it programatically you would have something like this in your viewWillAppear (or wherever it fits you) call:
[_mySlider addTarget:self
action:@selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
The receiving method would look like this:
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(@"Slider did end sliding... Do your stuff here");
}
回答3:
You can add an action that takes two parameters, sender and an 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
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 in Interface Builder when adding an action you also have the option to add both sender and event parameters to the action.
回答4:
Since UISlider
is a subclass of UIControl
, you can set a target and action for its UIControlEventTouchUpInside
.
If you want to do it in code, it looks like this:
[self.slider addTarget:self action:@selector(dragEndedForSlider:)
forControlEvents:UIControlEventTouchUpInside];
That will send you a dragEndedForSlider:
message when the touch ends.
If you want to do it in your nib, you can control-click your slider to get its connections menu, and then drag from the “Touch Up Inside” socket to the target object.
You should also add a target and action for UIControlEventTouchUpOutside
and for UIControlEventTouchCancel
.
回答5:
You can use:
- (void)addTarget:(id)target action:(SEL)action
forControlEvents:(UIControlEvents)controlEvents
to detect when the touchDown and touchUp events occur in UISlider
回答6:
Swift 4 and Swift 3
Add target for
touchUpInside
andtouchUpOutside
events. You can do it either programatically or from storyboard. This is how you do it programaticallyslider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Write your function to handle the end of slider drag
func sliderDidEndSliding() { print("end sliding") }
回答7:
I think you need the control event UIControlEventTouchUpInside
.
回答8:
Swift 3 answer
I had same problem and eventually got this to work, so maybe it will help somebody. Connect your_Slider to 'Value Changed' in storyboard and when slider moved "Slider Touched" actioned and when let go "Slider Released".
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
回答9:
Connect Touch Up Inside
and Value Changed
回答10:
Swift 3.1
Sometimes you will want the slider's drag events to fire continuously, but have the option of executing different code depending on whether the slider is still being dragged or has just finished being dragged.
To do this, I've expanded on Andy's answer above that makes use of the slider's isTracking
property. I needed to record two states: sliderHasFinishedTracking
and sliderLastStoredValue
.
My code correctly:
doesn't fire an action upon starting drag
fires the action if the user only nudges the slider with a single tap (meaning that
isTracking
remainsfalse
)
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.