Catatan di Interface Builder saat menambahkan tindakan, Anda juga memiliki opsi untuk menambahkan parameter pengirim dan peristiwa ke tindakan tersebut.
Bekerja dengan sempurna! Dari mana Anda mendapatkan sumbernya?
Roi Mulia
2
terima kasih @RoiMulia, Saya tidak ingat di mana saya pertama kali melihatnya, saya telah menggunakan slider selama bertahun-tahun. Terkadang saya menggunakannya untuk mengabaikan perubahan pada UITouchPhaseEnded karena nilainya cenderung melonjak saat pengguna mengangkat jari mereka.
Devin Pitcher
2
Ingatlah untuk mengatur isContinuous = truedi Anda UISlider.
krlbsk
2
Ini adalah solusi yang bagus, namun ada masalah dengan pembatalan sentuh. Meskipun ada acara yang "dibatalkan" di enum touchEvent, itu tidak akan diaktifkan saat sentuhan dibatalkan. Oleh karena itu saya merekomendasikan juga menambahkan pendengar untuk acara touchCancel dari Slider. Ini harus mencakup semua kemungkinan.
bnussey
2
Saya melihat bahwa terkadang fase dapat berjalan: dimulai, diam, dipindahkan, tetapi kemudian tidak pernah berakhir atau dibatalkan. Ini bermasalah untuk kasus penggunaan saya karena saya mengharapkan setiap interaksi akan berakhir atau dibatalkan. Perbaikannya dicatat di atas: gunakan target / tindakan pembatalan sentuh yang terpisah.
Jordan H
71
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:
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 UIControlEventTouchUpOutsidedan untuk UIControlEventTouchCancel.
@rob mayoff Maaf, tetapi Anda perlu menggunakan UIControlEventTouchUpOutside. Jika tidak, pemilih tidak akan dipanggil jika jari Anda tidak berada di penggeser setelah Anda selesai menyeret.
pengguna3164248
2
Perilaku UISlidertelah berubah sejak saya menulis jawaban ini.
merampok mayoff
Dapat mengonfirmasi bahwa Anda juga perlu mendaftarkan penangan untuk UIControlEventTouchUpOutside di iOS 9.
lms
Saya tidak pernah bisa memanggil UIControlEventTouchCancelpenangan di iOS 9. Tapi saya bisa memanggil UIControlEventTouchUpInsidedan UIControlEventTouchUpOutsidehanya.
petrsyn
17
Swift 5 dan Swift 4
Tambahkan target untuk touchUpInsidedan touchUpOutsideacara. Anda dapat melakukannya secara terprogram atau dari storyboard. Ini adalah cara Anda melakukannya secara terprogram
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".
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 isTrackingproperti slider . Saya perlu mencatat dua status: sliderHasFinishedTrackingdan sliderLastStoredValue.
Kode saya dengan benar:
tidak mengaktifkan tindakan saat memulai tarik
mengaktifkan tindakan jika pengguna hanya mendorong slider dengan satu ketukan (artinya isTrackingtetap false)
classSliderExample: UIViewController{
var slider: UISlider = UISlider()
var sliderHasFinishedTracking: Bool = truevar sliderLastStoredValue: Float!overridefuncloadView() {
super.loadView()
slider.minimumValue = 100.0
slider.maximumValue = 200.0
slider.isContinuous = true
slider.value = 100.0self.sliderLastStoredValue = slider.value
slider.addTarget(self, action: #selector(respondToSlideEvents), for: .valueChanged)
// add your slider to the view however you like
}
funcrespondToSlideEvents(sender: UISlider) {
let currentValue: Float = Float(sender.value)
print("Event fired. Current value for slider: \(currentValue)%.")
if(slider.isTracking) {
self.sliderHasFinishedTracking = falseprint("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 = trueprint("Action upon slider drag/tap finishing ⌛️")
}
}
self.sliderLastStoredValue = currentValue
}
}
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.
@IBActionfuncactionSlider(_ sender: Any) {
let value = sliderSpeed.value.rounded()
}
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
sumber
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.
sumber
isContinuous = true
di AndaUISlider
.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"); }
sumber
Karena
UISlider
merupakan subkelas dariUIControl
, Anda dapat menetapkan target dan tindakan untuknyaUIControlEventTouchUpInside
.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 untukUIControlEventTouchCancel
.sumber
UISlider
telah berubah sejak saya menulis jawaban ini.UIControlEventTouchCancel
penangan di iOS 9. Tapi saya bisa memanggilUIControlEventTouchUpInside
danUIControlEventTouchUpOutside
hanya.Swift 5 dan Swift 4
Tambahkan target untuk
touchUpInside
dantouchUpOutside
acara. Anda dapat melakukannya secara terprogram atau dari storyboard. Ini adalah cara Anda melakukannya secara terprogramslider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Tuliskan fungsi Anda untuk menangani akhir seret penggeser
func sliderDidEndSliding() { print("end sliding") }
sumber
Kamu bisa memakai:
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
untuk mendeteksi kapan peristiwa touchDown dan touchUp terjadi di UISlider
sumber
Saya pikir Anda membutuhkan acara kontrol
UIControlEventTouchUpInside
.sumber
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") } }
sumber
Hubungkan
Touch Up Inside
danValue Changed
sumber
Swift 3.1.0
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
dansliderLastStoredValue
.Kode saya dengan benar:
tidak mengaktifkan tindakan saat memulai tarik
mengaktifkan tindakan jika pengguna hanya mendorong slider dengan satu ketukan (artinya
isTracking
tetapfalse
)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 } }
sumber
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)") }
sumber
Mungkin Anda harus menambahkan target untuk acara UIControlEventTouchUpInside 、 UIControlEventTouchUpOutside 、 UIControlEventTouchCancel.
Saya bertemu masalah yang sama sebelumnya, karena saya tidak menambahkan target untuk acara UIControlEventTouchCancel .
sumber
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.
sumber
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); }
sumber
RxSwift:
self.slider.rx.controlEvent([.touchUpInside, .touchUpOutside]) .bind(to: self.viewModel.endSlidingSlider) .disposed(by: self.disposeBag)
sumber
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() }
sumber