¿Cómo detectar el evento cuando el usuario ha terminado de arrastrar un puntero deslizante?
¿Cómo detectar el evento cuando el usuario ha terminado de arrastrar un puntero deslizante?
Respuestas:
Si no necesita ningún dato entre el arrastre, simplemente debe configurar:
[mySlider setContinuous: NO];
De esta manera, recibirá el valueChanged
evento solo cuando el usuario deje de mover el control deslizante.
Versión Swift 5 :
mySlider.isContinuous = false
Events [x] Continuous Updates
configuración para UISliderView. Al desmarcar esto, se establece continuous
en falso / NO.
self.mySlider.isContinuous = false
Puede agregar una acción que tome dos parámetros, remitente y un evento, para UIControlEventValueChanged:
[slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged]
Luego verifique la fase del objeto táctil en su controlador:
- (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 y 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
}
}
}
Tenga en cuenta que en Interface Builder al agregar una acción, también tiene la opción de agregar parámetros de remitente y de evento a la acción.
isContinuous = true
su UISlider
.
Utilizo las notificaciones "Retocar en el interior" y "Retocar en el exterior".
Constructor de interfaces:
Conecte ambas notificaciones en Interface Builder a su método de recepción. El método podría verse así:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
En codigo:
Si desea conectarlo programáticamente, tendría algo como esto en su viewWillAppear (o donde se ajuste a usted) llame:
[_mySlider addTarget:self
action:@selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
El método de recepción se vería así:
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Dado que UISlider
es una subclase de UIControl
, puede establecer un objetivo y una acción para suUIControlEventTouchUpInside
.
Si desea hacerlo en código, se ve así:
[self.slider addTarget:self action:@selector(dragEndedForSlider:)
forControlEvents:UIControlEventTouchUpInside];
Eso te enviará un dragEndedForSlider:
mensaje cuando termine el toque.
Si desea hacerlo en su plumilla, puede controlar y hacer clic en el control deslizante para obtener su menú de conexiones y luego arrastrar desde el zócalo "Retocar dentro" hasta el objeto de destino.
También debe agregar un objetivo y una acción para UIControlEventTouchUpOutside
y para UIControlEventTouchCancel
.
UISlider
ha cambiado desde que escribí esta respuesta.
UIControlEventTouchCancel
controlador en iOS 9. Pero puedo invocar UIControlEventTouchUpInside
y UIControlEventTouchUpOutside
solo.
Agregar destino para eventos touchUpInside
y touchUpOutside
. Puede hacerlo programáticamente o desde el guión gráfico. Así es como lo haces programáticamente
slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Escriba su función para manejar el final del arrastre del control deslizante
func sliderDidEndSliding() {
print("end sliding")
}
Puedes usar:
- (void)addTarget:(id)target action:(SEL)action
forControlEvents:(UIControlEvents)controlEvents
para detectar cuándo ocurren los eventos touchDown y touchUp en UISlider
Creo que necesitas el evento de control UIControlEventTouchUpInside
.
Respuesta rápida 3
Tuve el mismo problema y finalmente logré que esto funcionara, así que tal vez ayude a alguien. Conecte your_Slider a 'Value Changed' en el guión gráfico y cuando el control deslizante se movió, se activó "Control deslizante tocado" y cuando se soltó "Control deslizante liberado".
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
A veces querrá que los eventos de arrastre del control deslizante se activen continuamente, pero tiene la opción de ejecutar un código diferente dependiendo de si el control deslizante todavía se está arrastrando o acaba de terminar de arrastrarse.
Para hacer esto, he ampliado la respuesta de Andy anterior que hace uso de la isTracking
propiedad del control deslizante . Necesitaba registrar dos estados: sliderHasFinishedTracking
y sliderLastStoredValue
.
Mi código correctamente:
no dispara una acción al iniciar el arrastre
dispara la acción si el usuario solo empuja el control deslizante con un solo toque (lo que significa que isTracking
permanece 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
}
}
En Swift 4 puedes usar esta función
1 primer paso: - Agregar el objetivo en el control deslizante
self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside]))
2 Segundo paso: - Crear una función
@objc func sliderDidEndSliding(notification: NSNotification)
{
print("Hello-->\(distanceSlider.value)")
}
Tuve un problema similar recientemente. Esto es lo que hice en Swift:
theSlider.continuous = false;
El código que contiene este valor continuo dice:
public var continuous: Bool // if set, value change events are generated
// any time the value changes due to dragging. default = YES
El valor predeterminado parece ser SÍ (verdadero). Establecerlo en falso hace lo que desea.
Prueba así
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);
}
RxSwift:
self.slider.rx.controlEvent([.touchUpInside, .touchUpOutside])
.bind(to: self.viewModel.endSlidingSlider)
.disposed(by: self.disposeBag)
Cree una acción y una salida para el control deslizante (o puede encasillar al remitente de la acción a UISlider) y, en la interfaz de usuario, desmarque la casilla de verificación Actualizaciones continuas. De esta forma obtendremos el valor del control deslizante solo cuando el control deslizante deje de arrastrar.
@IBAction func actionSlider(_ sender: Any) {
let value = sliderSpeed.value.rounded()
}