Як виявити подію, коли користувач закінчив перетягування повзунка?
Як виявити подію, коли користувач закінчив перетягування повзунка?
Відповіді:
Якщо вам не потрібні дані між перетягуванням, вам слід просто встановити:
[mySlider setContinuous: NO];
Таким чином ви отримаєте valueChanged
подію лише тоді, коли користувач перестане рухати повзунок.
Версія Swift 5 :
mySlider.isContinuous = false
self.mySlider.isContinuous = false
Ви можете додати дію, яка приймає два параметри, відправника та подію, для UIControlEventValueChanged:
[slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged]
Потім перевірте фазу дотику до вашого обробника:
- (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;
}
}
Свіфт 4 і 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
}
}
}
Примітка у Interface Builder, додаючи дію, ви також можете додати до дії параметри відправника та події.
isContinuous = true
у вашому UISlider
.
Я використовую сповіщення "Touch Up Inside" та "Touch up outside".
Конструктор інтерфейсів:
Підключіть обидва сповіщення у Interface Builder до способу отримання. Метод може виглядати так:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
У коді:
Якщо ви хочете підключити його програмно, у вас буде щось подібне у вашому viewWillAppear (або там, де це вам підходить), зателефонуйте:
[_mySlider addTarget:self
action:@selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
Метод отримання буде виглядати так:
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Оскільки UISlider
це підклас UIControl
, ви можете встановити ціль і дію для нього UIControlEventTouchUpInside
.
Якщо ви хочете зробити це в коді, це виглядає так:
[self.slider addTarget:self action:@selector(dragEndedForSlider:)
forControlEvents:UIControlEventTouchUpInside];
Це надішле вам dragEndedForSlider:
повідомлення, коли дотик закінчиться.
Якщо ви хочете зробити це за допомогою перо, ви можете натиснути на повзунок, клацнувши клавішу управління, щоб отримати меню його з'єднань, а потім перетягнути з гнізда “Touch Up Inside” до цільового об’єкта.
Слід також додати ціль і дії для UIControlEventTouchUpOutside
і за UIControlEventTouchCancel
.
UISlider
моменту написання цієї відповіді поведінка користувача змінилася.
UIControlEventTouchCancel
обробник в iOS 9. Але я можу викликати UIControlEventTouchUpInside
і UIControlEventTouchUpOutside
лише.
Додати мета для touchUpInside
і touchUpOutside
подій. Ви можете зробити це або програмно, або з розкадровки. Це як ви робите це програмно
slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Напишіть свою функцію для обробки кінця перетягування повзунка
func sliderDidEndSliding() {
print("end sliding")
}
Ви можете використовувати:
- (void)addTarget:(id)target action:(SEL)action
forControlEvents:(UIControlEvents)controlEvents
щоб виявити, коли в UISlider відбуваються події touchDown та touchUp
Я думаю, вам потрібна контрольна подія UIControlEventTouchUpInside
.
Швидка відповідь 3
У мене була така сама проблема, і врешті-решт це змусило працювати, тож, можливо, це допоможе комусь Підключіть your_Slider до 'Значення змінено' в розкадровці, і коли повзунок переміщується "Повзунок торкнувся" діяв, а коли відпустив "Повзунок звільнений".
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
Іноді вам захочеться, щоб події перетягування повзунка спрацьовували безперервно, але у вас є можливість виконувати інший код, залежно від того, перетягується повзунок, чи він щойно закінчив.
Для цього я розширив відповідь Енді вище, яка використовує isTracking
властивість повзунка . Мені потрібно було записати два стани: sliderHasFinishedTracking
іsliderLastStoredValue
.
Мій код правильно:
не запускає дію при запуску перетягування
запускає дію, якщо користувач штовхає повзунок лише одним натисканням (означає, що isTracking
залишається 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
}
}
У Swift 4 ви можете використовувати цю функцію
1 перший крок: - Додавання цілі в повзунок
self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside]))
2 Другий крок: - Створіть функцію
@objc func sliderDidEndSliding(notification: NSNotification)
{
print("Hello-->\(distanceSlider.value)")
}
Нещодавно у мене була подібна проблема. Ось що я зробив у Свіфті:
theSlider.continuous = false;
Код, що містить це безперервне значення, читає:
public var continuous: Bool // if set, value change events are generated
// any time the value changes due to dragging. default = YES
Здається, за замовчуванням ТАК (істинно). Якщо встановити значення false, це робить те, що ви хочете.
Спробуйте так
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)
Створіть дію та розетку для повзунка (або ви можете ввести відправника від дії до UISlider) і в інтерфейсі зніміть прапорець Неперервні оновлення. Таким чином ми отримаємо значення повзунка лише тоді, коли повзунок перестане перетягуватися.
@IBAction func actionSlider(_ sender: Any) {
let value = sliderSpeed.value.rounded()
}