Bagaimana cara mendeteksi acara ketika pengguna telah mengakhiri seret penunjuk penggeser?
Bagaimana cara mendeteksi acara ketika pengguna telah mengakhiri seret penunjuk penggeser?
Jawaban:
Jika Anda tidak memerlukan data apa pun di antara seret, Anda cukup menyetel:
[mySlider setContinuous: NO];
Dengan cara ini Anda akan menerima valueChanged
acara hanya ketika pengguna berhenti menggerakkan slider.
Versi Swift 5 :
mySlider.isContinuous = false
self.mySlider.isContinuous = false
Anda dapat menambahkan tindakan yang membutuhkan dua parameter, pengirim dan peristiwa, untuk UIControlEventValueChanged:
[slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged]
Kemudian periksa fase objek sentuh di pawang Anda:
- (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;
}
}
Cepat 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
}
}
}
Catatan di Interface Builder saat menambahkan tindakan, Anda juga memiliki opsi untuk menambahkan parameter pengirim dan peristiwa ke tindakan tersebut.
isContinuous = true
di Anda UISlider
.
Saya menggunakan notifikasi "Touch Up Inside" dan "Touch up outside".
Pembuat Antarmuka:
Hubungkan kedua notifikasi di Interface Builder ke metode penerimaan Anda. Metodenya bisa seperti ini:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Dalam kode:
Jika Anda ingin menyambungkannya secara terprogram, Anda akan memiliki sesuatu seperti ini di viewWillAppear Anda (atau di mana pun itu cocok untuk Anda) panggilan:
[_mySlider addTarget:self
action:@selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
Metode penerimaan akan terlihat seperti ini:
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Karena UISlider
merupakan subkelas dari UIControl
, Anda dapat menetapkan target dan tindakan untuknya UIControlEventTouchUpInside
.
Jika Anda ingin melakukannya dalam kode, tampilannya seperti ini:
[self.slider addTarget:self action:@selector(dragEndedForSlider:)
forControlEvents:UIControlEventTouchUpInside];
Itu akan mengirimi Anda dragEndedForSlider:
pesan saat sentuhan berakhir.
Jika Anda ingin melakukannya di ujung pena, Anda dapat mengontrol-klik penggeser untuk mendapatkan menu koneksinya, lalu seret dari soket "Touch Up Inside" ke objek target.
Anda juga harus menambahkan target dan tindakan untuk UIControlEventTouchUpOutside
dan untuk UIControlEventTouchCancel
.
UISlider
telah berubah sejak saya menulis jawaban ini.
UIControlEventTouchCancel
penangan di iOS 9. Tapi saya bisa memanggil UIControlEventTouchUpInside
dan UIControlEventTouchUpOutside
hanya.
Tambahkan target untuk touchUpInside
dan touchUpOutside
acara. Anda dapat melakukannya secara terprogram atau dari storyboard. Ini adalah cara Anda melakukannya secara terprogram
slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Tuliskan fungsi Anda untuk menangani akhir seret penggeser
func sliderDidEndSliding() {
print("end sliding")
}
Kamu bisa memakai:
- (void)addTarget:(id)target action:(SEL)action
forControlEvents:(UIControlEvents)controlEvents
untuk mendeteksi kapan peristiwa touchDown dan touchUp terjadi di UISlider
Saya pikir Anda membutuhkan acara kontrol UIControlEventTouchUpInside
.
Jawaban cepat 3
Saya memiliki masalah yang sama dan akhirnya berhasil, jadi mungkin ini akan membantu seseorang. Hubungkan your_Slider ke 'Value Changed' di storyboard dan ketika slider digerakkan, "Slider Touched" bertindak dan saat melepaskan "Slider Released".
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
Terkadang Anda ingin peristiwa seret penggeser diaktifkan terus-menerus, tetapi memiliki opsi untuk menjalankan kode yang berbeda tergantung pada apakah penggeser masih diseret atau baru selesai diseret.
Untuk melakukan ini, saya telah memperluas jawaban Andy di atas yang menggunakan isTracking
properti slider . Saya perlu mencatat dua status: sliderHasFinishedTracking
dan sliderLastStoredValue
.
Kode saya dengan benar:
tidak mengaktifkan tindakan saat memulai tarik
mengaktifkan tindakan jika pengguna hanya mendorong slider dengan satu ketukan (artinya isTracking
tetap 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
}
}
Di Swift 4 Anda dapat menggunakan fungsi ini
1 Langkah pertama: - Menambahkan target di slider
self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside]))
2 Langkah kedua: - Membuat fungsi
@objc func sliderDidEndSliding(notification: NSNotification)
{
print("Hello-->\(distanceSlider.value)")
}
Saya mengalami masalah serupa baru-baru ini. Inilah yang saya lakukan di Swift:
theSlider.continuous = false;
Kode yang menyimpan nilai berkelanjutan ini berbunyi:
public var continuous: Bool // if set, value change events are generated
// any time the value changes due to dragging. default = YES
Defaultnya tampaknya YA (benar). Menyetelnya menjadi salah melakukan hal yang Anda inginkan.
Coba seperti ini
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)
Buat tindakan dan outlet untuk slider (atau Anda dapat mengetik pengirim dari tindakan ke UISlider), dan di UI Hapus centang kotak Pembaruan Berkelanjutan. Dengan cara ini kita akan mendapatkan nilai slider hanya ketika slider berhenti menyeret.
@IBAction func actionSlider(_ sender: Any) {
let value = sliderSpeed.value.rounded()
}