2011-08-16 4 views
34

Chciałbym, aby zatrzymać suwak w dyskretnych punktów, które reprezentują liczby całkowite na osi czasu. Jaki jest najlepszy sposób na zrobienie tego? Nie chcę żadnych wartości pomiędzy. Byłoby świetnie, gdyby suwak mógł "przyciągnąć" do pozycji również w każdym dyskretnym punkcie.iOS jak zrobić suwak zatrzymać w dyskretnych punktów

Odpowiedz

35

Aby suwak "zakleszczył" się w określonych punktach, twój kontroler powinien, w metodzie valueChanged powiązanej z suwakiem, określić odpowiedni zaokrąglony z wartości suwaka, a następnie użyć parametru setValue: animated: aby przesunąć suwak do odpowiednie miejsce. Jeśli więc suwak zmieni się z 0 na 2, a użytkownik zmieni go na 0.75, zakładamy, że powinno to wynosić 1 i ustawić wartość suwaka na tę wartość.

+5

Jak mówi Nathan poniżej, użyj "Dotykaj wewnątrz", ponieważ będzie migotać podczas przeciągania, jeśli użyjesz valueChanged – Zenuka

+1

To dotyczy tylko suwaka ciągłego, ale tak, w takim przypadku jest to lepsze rozwiązanie. – jrturton

60

Kroki, które zrobiłem, były w zasadzie takie same, jak podano w odpowiedzi jrturtona, ale zauważyłem, że suwak nieco opóźnił się w stosunku do moich ruchów. Oto, jak to zrobiłem:

Umieść suwak w widoku w programie Interface Builder. Ustaw wartości min/max suwaka. (Użyłem 0 i 5)

W pliku .h:

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

W pliku .m:

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

po tym w konstruktorze Interface I związał się z „dotykowej wewnątrz "wydarzenie dla suwaka dla właściciela pliku, a nie dla" Zmienionej wartości ". Teraz pozwala mi płynnie przesuwać suwak i przyciąga do każdej liczby całkowitej, gdy podnoszę palec.

Dzięki @jrturton!

UPDATE - Swift:

@IBOutlet var mySlider: UISlider! 

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

Także jeśli istnieją jakiekolwiek zamieszanie na rzeczy zaczepiania się w serii ujęć Przesłałem krótki przykład do GitHub: https://github.com/nathandries/StickySlider

+2

Fajnie, ale to " Zaokrąglone w dół. lroundf zaokrągli do najbliższej liczby całkowitej. –

+1

Użyłbym również "Touch Up Outside" – Zenuka

5

Co zrobiłem tego jest najpierw ustaw zmienną "output" bieżącego suwaka na liczbę całkowitą (domyślnie float). Następnie ustaw numer wyjściowy jako bieżącą wartość suwaka:

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

Spowoduje to przesunięcie w przyrostach o 1 liczbę całkowitą. Aby poruszać się w określonym zakresie liczb, powiedzmy na przykład za 5 s, zmodyfikuj wartość wyjściową za pomocą następującej formuły. Dodaj to między dwoma pierwszymi liniami powyżej:

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

Teraz twój suwak "przeskakuje" do wielokrotności 5 podczas przesuwania.

4

Zrobiłem jak sugeruje Nathan, ale również chcę zaktualizować skojarzony UILabel wyświetlanie aktualnej wartości w czasie rzeczywistym, więc o to, co zrobiłem:

- (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]; 
    } 
} 

Wadą, oczywiście, o to chodzi wykonuje dwa działania (metody) na suwak.