Jak wykryć zdarzenie, gdy użytkownik zakończył przeciąganie wskaźnika suwaka?
Jak wykryć zdarzenie, gdy użytkownik zakończył przeciąganie wskaźnika suwaka?
Odpowiedzi:
Jeśli nie potrzebujesz żadnych danych pomiędzy przeciąganiem, po prostu ustaw:
[mySlider setContinuous: NO];
W ten sposób valueChanged
zdarzenie otrzymasz tylko wtedy, gdy użytkownik przestanie przesuwać suwak.
Wersja Swift 5 :
mySlider.isContinuous = false
self.mySlider.isContinuous = false
Możesz dodać akcję, która przyjmuje dwa parametry, nadawcę i zdarzenie, dla UIControlEventValueChanged:
[slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged]
Następnie sprawdź fazę obiektu dotykowego w twoim programie obsługi:
- (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 i 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
}
}
}
Uwaga w programie Interface Builder podczas dodawania akcji można również dodać do akcji parametry nadawcy i zdarzenia.
isContinuous = true
w swoim UISlider
.
Korzystam z powiadomień „Retusz wewnątrz” i „Poprawianie na zewnątrz”.
Konstruktor interfejsu:
Połącz oba powiadomienia w Interface Builder z metodą odbierania. Metoda mogłaby wyglądać następująco:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
W kodzie:
Jeśli chcesz podłączyć to programowo, powinieneś mieć coś takiego w swoim wywołaniu viewWillAppear (lub gdziekolwiek to pasuje):
[_mySlider addTarget:self
action:@selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
Sposób odbioru wyglądałby następująco:
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Ponieważ UISlider
jest to podklasa UIControl
, możesz ustawić cel i akcję dla jej UIControlEventTouchUpInside
.
Jeśli chcesz to zrobić w kodzie, wygląda to tak:
[self.slider addTarget:self action:@selector(dragEndedForSlider:)
forControlEvents:UIControlEventTouchUpInside];
To wyśle ci dragEndedForSlider:
wiadomość po zakończeniu dotknięcia.
Jeśli chcesz to zrobić w końcówce, możesz kliknąć suwak z wciśniętym klawiszem Control, aby wyświetlić menu połączeń, a następnie przeciągnąć z gniazda „Touch Up Inside” do obiektu docelowego.
Powinieneś także dodać cel i akcję dla UIControlEventTouchUpOutside
i dla UIControlEventTouchCancel
.
UISlider
zmieniło się od czasu napisania tej odpowiedzi.
UIControlEventTouchCancel
obsługi w iOS 9. Ale mogę wywołać UIControlEventTouchUpInside
i UIControlEventTouchUpOutside
tylko.
Dodaj cel dla touchUpInside
i touchUpOutside
wydarzeń. Możesz to zrobić programowo lub z poziomu storyboardu. W ten sposób robisz to programowo
slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Napisz swoją funkcję do obsługi końca przeciągania suwaka
func sliderDidEndSliding() {
print("end sliding")
}
Możesz użyć:
- (void)addTarget:(id)target action:(SEL)action
forControlEvents:(UIControlEvents)controlEvents
do wykrywania zdarzeń touchDown i touchUp w UISlider
Myślę, że potrzebujesz zdarzenia kontrolnego UIControlEventTouchUpInside
.
Szybka 3 odpowiedź
Miałem ten sam problem iw końcu udało mi się to zadziałać, więc może to komuś pomoże. Połącz your_Slider z „Zmieniono wartość” w scenorysie, a gdy suwak zostanie przesunięty, „Dotykany suwak” zadziała, a po puszczeniu „Zwolniony suwak”.
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
Czasami chcesz, aby zdarzenia przeciągania suwaka były uruchamiane w sposób ciągły, ale masz możliwość wykonania innego kodu w zależności od tego, czy suwak jest nadal przeciągany, czy właśnie zakończył przeciąganie.
Aby to zrobić, rozszerzyłem powyższą odpowiedź Andy'ego, która wykorzystuje właściwość suwaka isTracking
. Musiałem nagrać dwa stany: sliderHasFinishedTracking
isliderLastStoredValue
.
Mój kod poprawnie:
nie uruchamia akcji po rozpoczęciu przeciągania
uruchamia akcję, jeśli użytkownik tylko przesuwa suwak jednym dotknięciem (co oznacza, że isTracking
pozostaje 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
}
}
W Swift 4 możesz użyć tej funkcji
1 Pierwszy krok: - Dodanie celu w suwaku
self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside]))
2 Drugi krok: - Utwórz funkcję
@objc func sliderDidEndSliding(notification: NSNotification)
{
print("Hello-->\(distanceSlider.value)")
}
Niedawno miałem podobny problem. Oto, co zrobiłem w Swift:
theSlider.continuous = false;
Kod, który przechowuje tę ciągłą wartość, czyta:
public var continuous: Bool // if set, value change events are generated
// any time the value changes due to dragging. default = YES
Domyślną wartością wydaje się TAK (prawda). Ustawienie wartości false robi to, czego chcesz.
Spróbuj w ten sposób
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)
Utwórz akcję i wylot dla suwaka (lub możesz wysłać nadawcę z akcji do UISlider) i w interfejsie użytkownika usuń zaznaczenie pola wyboru Ciągłe aktualizacje. W ten sposób wartość suwaka uzyskamy tylko wtedy, gdy suwak przestanie się przeciągać.
@IBAction func actionSlider(_ sender: Any) {
let value = sliderSpeed.value.rounded()
}