Как определить событие, когда пользователь закончил перетаскивание указателя ползунка?
Как определить событие, когда пользователь закончил перетаскивание указателя ползунка?
Ответы:
Если вам не нужны данные между перетаскиванием, вы должны просто установить:
[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;
}
}
Swift 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
}
}
}
Обратите внимание, что в Интерфейсном Разработчике при добавлении действия у вас также есть возможность добавить к действию параметры отправителя и события.
isContinuous = true
в вашем UISlider
.
Я использую уведомления «Подкрашивание изнутри» и «Подкрашивание снаружи».
Разработчик интерфейса:
Подключите оба уведомления в Интерфейсном Разработчике к вашему методу получения. Метод может выглядеть так:
- (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:
сообщение, когда касание закончится.
Если вы хотите сделать это в своем наконечнике, вы можете щелкнуть слайдер, удерживая клавишу Control, чтобы открыть меню подключений, а затем перетащить его из гнезда «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
для обнаружения событий touchDown и touchUp в UISlider
Я думаю, вам нужно контрольное событие UIControlEventTouchUpInside
.
Swift 3 ответ
У меня была такая же проблема, и в конце концов это заработало, так что, возможно, это кому-то поможет. Подключите your_Slider к «Value Changed» в раскадровке, и при перемещении слайдера «Slider Touched» активирован, а когда отпущен «Slider Released».
@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)")
}
Недавно у меня была аналогичная проблема. Вот что я сделал в Swift:
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()
}