Как да открием събитието, когато потребителят е прекратил плъзгането на показалец на плъзгач?
iPhone : Как да открия края на плъзгането на плъзгача?
Отговори (16)
Ако не се нуждаете от данни между плъзгането, трябва просто да зададете:
[mySlider setContinuous: NO];
По този начин ще получите valueChanged
събитие само когато потребителят спре да движи плъзгача.
Swift 5 версия:
mySlider.isContinuous = false
Events [x] Continuous Updates
настройка за UISliderView. Премахването на отметката задава continuous
на false/NO.
- person leanne; 14.07.2016
self.mySlider.isContinuous = false
- person Marco Weber; 16.12.2017
Можете да добавите действие, което приема два параметъра, подател и събитие, за 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, когато добавяте действие, вие също имате опцията да добавите към действието параметри на изпращача и събитието.
allTouches
, които принадлежат към различни фази?
- person David; 10.03.2017
isContinuous = true
във вашия UISlider
.
- person krlbsk; 20.09.2017
allTouches
ще бъде nil
при увеличаване/намаляване на стойността с VoiceOver.
- person Jordan H; 28.01.2020
Използвам известията „Ретуширане отвътре“ и „Ретуширане отвън“.
Конструктор на интерфейс:
Свържете двете известия в Interface Builder с вашия метод на получаване. Методът може да изглежда така:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
В код:
Ако искате да го свържете програмно, ще имате нещо подобно във вашия viewWillAppear (или където ви е удобно) call:
[_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
се промени, откакто написах този отговор.
- person rob mayoff; 11.04.2015
UIControlEventTouchCancel
манипулатор в iOS 9. Но мога да извикам само UIControlEventTouchUpInside
и UIControlEventTouchUpOutside
.
- person petrsyn; 29.09.2016
Swift 5 и Swift 4
Добавете цел за
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
Имах същия проблем и в крайна сметка го накарах, така че може би ще помогне на някого. Свържете вашия_плъзгач към „Променена стойност“ в сценария и когато плъзгачът се премести, „Плъзгачът е докоснат“ действа, а когато го пуснете, „Плъзгачът е освободен“.
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
Swift 3.1
Понякога ще искате събитията за плъзгане на плъзгача да се задействат непрекъснато, но имате възможност да изпълните различен код в зависимост от това дали плъзгачът все още се плъзга или току-що е приключил плъзгането.
За да направя това, разширих отговора на Анди по-горе, който използва на плъзгача 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)")
}
Може би трябва да добавите цел за UIControlEventTouchUpInside、UIControlEventTouchUpOutside、UIControlEventTouchCancel събития.
Срещнах същия проблем преди, защото не добавям цел за събитие UIControlEventTouchCancel.
Наскоро имах подобен проблем. Ето какво направих в 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()
}