Comment détecter l'événement lorsque l'utilisateur a terminé le glissement d'un curseur de curseur?
Comment détecter l'événement lorsque l'utilisateur a terminé le glissement d'un curseur de curseur?
Réponses:
Si vous n'avez pas besoin de données entre les glissements, vous devez simplement définir:
[mySlider setContinuous: NO];
De cette façon, vous recevrez un valueChanged
événement uniquement lorsque l'utilisateur arrête de déplacer le curseur.
Version Swift 5 :
mySlider.isContinuous = false
Events [x] Continuous Updates
paramètres pour UISliderView. Décocher cette option est définie continuous
sur false / NO.
self.mySlider.isContinuous = false
Vous pouvez ajouter une action qui prend deux paramètres, l'expéditeur et un événement, pour UIControlEventValueChanged:
[slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged]
Vérifiez ensuite la phase de l'objet tactile dans votre gestionnaire:
- (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 et 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
}
}
}
Remarque dans Interface Builder lors de l'ajout d'une action, vous avez également la possibilité d'ajouter à la fois des paramètres d'expéditeur et d'événement à l'action.
isContinuous = true
votre UISlider
.
J'utilise les notifications «Retouche à l'intérieur» et «Retouche à l'extérieur».
Constructeur d'interface:
Connectez les deux notifications dans Interface Builder à votre méthode de réception. La méthode pourrait ressembler à ceci:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Dans du code:
Si vous voulez le câbler par programme, vous auriez quelque chose comme ça dans votre viewWillAppear (ou partout où cela vous convient) appelez:
[_mySlider addTarget:self
action:@selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
La méthode de réception ressemblerait à ceci:
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Puisqu'il UISlider
s'agit d'une sous-classe de UIControl
, vous pouvez définir une cible et une action pour sonUIControlEventTouchUpInside
.
Si vous voulez le faire dans le code, cela ressemble à ceci:
[self.slider addTarget:self action:@selector(dragEndedForSlider:)
forControlEvents:UIControlEventTouchUpInside];
Cela vous enverra un dragEndedForSlider:
message lorsque le toucher se terminera.
Si vous voulez le faire dans votre plume, vous pouvez contrôler-cliquez sur votre curseur pour obtenir son menu de connexions, puis faites-le glisser de la prise «Retouche à l'intérieur» vers l'objet cible.
Vous devez également ajouter une cible et une action pour UIControlEventTouchUpOutside
et pour UIControlEventTouchCancel
.
UISlider
a changé depuis que j'ai écrit cette réponse.
UIControlEventTouchCancel
gestionnaire dans iOS 9. Mais je suis capable de l'invoquer UIControlEventTouchUpInside
et UIControlEventTouchUpOutside
uniquement.
Ajoutez une cible pour touchUpInside
et des touchUpOutside
événements. Vous pouvez le faire soit par programme, soit à partir du storyboard. Voici comment vous procédez par programme
slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Écrivez votre fonction pour gérer la fin du glissement du curseur
func sliderDidEndSliding() {
print("end sliding")
}
Vous pouvez utiliser:
- (void)addTarget:(id)target action:(SEL)action
forControlEvents:(UIControlEvents)controlEvents
pour détecter quand les événements touchDown et touchUp se produisent dans UISlider
Je pense que vous avez besoin de l'événement de contrôle UIControlEventTouchUpInside
.
Réponse Swift 3
J'ai eu le même problème et j'ai finalement réussi à faire fonctionner cela, alors peut-être que cela aidera quelqu'un. Connectez your_Slider à 'Value Changed' dans le storyboard et lorsque le curseur a bougé "Slider Touched" actionné et quand relâchez "Slider Released".
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
Parfois, vous souhaiterez que les événements de glissement du curseur se déclenchent en continu, mais vous avez la possibilité d'exécuter un code différent selon que le curseur est toujours en cours de déplacement ou qu'il vient de finir de le faire.
Pour ce faire, j'ai développé la réponse d'Andy ci-dessus qui utilise la isTracking
propriété du curseur . J'avais besoin d'enregistrer deux états: sliderHasFinishedTracking
etsliderLastStoredValue
.
Mon code correctement:
ne déclenche pas d'action au début de la traînée
déclenche l'action si l'utilisateur ne déplace le curseur que d'un seul clic (ce qui signifie qu'il isTracking
reste 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
}
}
Dans Swift 4, vous pouvez utiliser cette fonction
1 Première étape: - Ajout de la cible dans le curseur
self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside]))
2 Deuxième étape: - Créer une fonction
@objc func sliderDidEndSliding(notification: NSNotification)
{
print("Hello-->\(distanceSlider.value)")
}
J'ai eu un problème similaire récemment. Voici ce que j'ai fait dans Swift:
theSlider.continuous = false;
Le code qui contient cette valeur continue lit:
public var continuous: Bool // if set, value change events are generated
// any time the value changes due to dragging. default = YES
La valeur par défaut semble être OUI (vrai). Le définir sur false fait ce que vous voulez.
Essayez comme ça
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)
Créez une action et une sortie pour le curseur (ou vous pouvez taper l'expéditeur de l'action vers UISlider), et dans l'interface utilisateur, décochez la case Mises à jour continues. De cette façon, nous obtiendrons la valeur du curseur uniquement lorsque le curseur cesse de glisser.
@IBAction func actionSlider(_ sender: Any) {
let value = sliderSpeed.value.rounded()
}