web-dev-qa-db-fra.com

iOS comment arrêter le curseur à des points discrets

Je voudrais faire un arrêt de curseur à des points discrets qui représentent des entiers sur une chronologie. Quelle est la meilleure façon de procéder? Je ne veux aucune valeur entre les deux. Ce serait formidable si le curseur pouvait "se caler" pour se positionner à chaque point discret également.

42
gonzobrains

Pour que le curseur "colle" à des points spécifiques, votre contrôleur de vue doit, dans la méthode valueChanged liée au curseur, déterminer l'arrondi approprié à partir de la valeur du curseur, puis utiliser setValue: animated: pour déplacer le curseur à l'endroit approprié. Donc, si votre curseur passe de 0 à 2 et que l'utilisateur le modifie à 0,75, vous supposez que cela devrait être 1 et définissez la valeur du curseur sur cela.

39
jrturton

Les mesures que j'ai prises ici étaient à peu près les mêmes que celles indiquées dans la réponse de jrturton, mais j'ai constaté que le curseur serait en quelque sorte en retard sur mes mouvements. Voici comment j'ai fait ça:

Placez le curseur dans la vue dans Interface Builder. Définissez les valeurs min/max du curseur. (J'ai utilisé 0 et 5)

Dans le fichier .h:

@property (strong, nonatomic) IBOutlet UISlider *mySlider;
- (IBAction)sliderChanged:(id)sender;

Dans le fichier .m:

- (IBAction)sliderChanged:(id)sender 
{
    int sliderValue;
    sliderValue = lroundf(mySlider.value);
    [mySlider setValue:sliderValue animated:YES];
}

Après cela, dans Interface Builder, j'ai connecté l'événement "Touch Up Inside" pour le curseur au propriétaire du fichier, plutôt que "Value Changed". Maintenant, cela me permet de déplacer le curseur en douceur et de cliquer sur chaque nombre entier lorsque mon doigt est levé.

Merci @jrturton!

[~ # ~] mise à jour [~ # ~] - Swift:

@IBOutlet var mySlider: UISlider!

@IBAction func sliderMoved(sender: UISlider) {
    sender.setValue(Float(lroundf(mySlider.value)), animated: true)
}

Aussi, s'il y a une confusion sur le raccordement des choses dans le storyboard, j'ai téléchargé un exemple rapide sur github: https://github.com/nathandries/StickySlider

65
Nathan Dries

Ce que j'ai fait pour cela, c'est d'abord définir une variable "sortie" de la valeur actuelle du curseur sur un entier (c'est un flottant par défaut). Définissez ensuite le numéro de sortie comme valeur actuelle du curseur:

int output = (int)mySlider.value;
mySlider.value = output;

Cela le réglera pour se déplacer par incréments de 1 entier. Pour le faire bouger dans une plage spécifique de nombres, disons par exemple, en 5s, modifiez votre valeur de sortie avec la formule suivante. Ajoutez ceci entre les deux premières lignes ci-dessus:

int output = (int)mySlider.value;
int newValue = 5 * floor((output/5)+0.5);
mySlider.value = newValue;

Maintenant, votre curseur "saute" à des multiples de 5 lorsque vous le déplacez.

6
ctlockey

J'ai fait comme Nathan l'a suggéré, mais je veux également mettre à jour un UILabel associé affichant la valeur actuelle en temps réel, alors voici ce que j'ai fait:

- (IBAction) countdownSliderChanged:(id)sender
{
    // Action Hooked to 'Value Changed' (continuous)

    // Update label (to rounded value)

    CGFloat value = [_countdownSlider value];

    CGFloat roundValue = roundf(value);

    [_countdownLabel setText:[NSString stringWithFormat:@" %2.0f 秒", roundValue]];
}


- (IBAction) countdownSliderFinishedEditing:(id)sender
{
    // Action Hooked to 'Touch Up Inside' (when user releases knob)

    // Adjust knob (to rounded value)

    CGFloat value = [_countdownSlider value];

    CGFloat roundValue = roundf(value);

    if (value != roundValue) {
        // Almost 100% of the time - Adjust:

        [_countdownSlider setValue:roundValue];
    }
}

L'inconvénient, bien sûr, est qu'il faut deux actions (méthodes) par curseur.

4
Nicolas Miari