Saya ingin bereaksi ketika seseorang mengguncang iPhone. Saya tidak terlalu peduli bagaimana mereka mengocoknya, hanya saja itu dilambaikan dengan penuh semangat selama sepersekian detik. Adakah yang tahu cara mendeteksi ini?
sumber
Saya ingin bereaksi ketika seseorang mengguncang iPhone. Saya tidak terlalu peduli bagaimana mereka mengocoknya, hanya saja itu dilambaikan dengan penuh semangat selama sepersekian detik. Adakah yang tahu cara mendeteksi ini?
Di 3.0, sekarang ada cara yang lebih mudah - hubungkan ke acara gerak baru.
Trik utamanya adalah Anda harus memiliki beberapa UIView (bukan UIViewController) yang Anda inginkan sebagai firstResponder untuk menerima pesan acara shake. Berikut kode yang dapat Anda gunakan di UIView apa pun untuk mendapatkan acara shake:
@implementation ShakingView
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if ( event.subtype == UIEventSubtypeMotionShake )
{
// Put in code here to handle shake
}
if ( [super respondsToSelector:@selector(motionEnded:withEvent:)] )
[super motionEnded:motion withEvent:event];
}
- (BOOL)canBecomeFirstResponder
{ return YES; }
@end
Anda dapat dengan mudah mengubah UIView (bahkan tampilan sistem) apa pun menjadi tampilan yang bisa mendapatkan peristiwa guncangan hanya dengan mensubklasifikasikan tampilan hanya dengan metode ini (dan kemudian memilih tipe baru ini, bukan tipe dasar dalam IB, atau menggunakannya saat mengalokasikan melihat).
Di pengontrol tampilan, Anda ingin mengatur tampilan ini menjadi responden pertama:
- (void) viewWillAppear:(BOOL)animated
{
[shakeView becomeFirstResponder];
[super viewWillAppear:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
[shakeView resignFirstResponder];
[super viewWillDisappear:animated];
}
Jangan lupa bahwa jika Anda memiliki tampilan lain yang menjadi responden pertama dari tindakan pengguna (seperti bilah pencarian atau bidang entri teks) Anda juga harus mengembalikan status guncangan tampilan responden pertama saat tampilan lain mengundurkan diri!
Metode ini berfungsi bahkan jika Anda mengatur applicationSupportsShakeToEdit ke NO.
viewDidAppear
bukanviewWillAppear
. Saya tidak yakin mengapa; mungkin tampilan harus terlihat sebelum dapat melakukan apa pun untuk mulai menerima acara goyang?motionEnded
sebelum goyang benar-benar berhenti. Jadi, dengan menggunakan pendekatan ini Anda mendapatkan serangkaian getar pendek yang terputus-putus, bukan satu yang panjang. Jawaban lain bekerja lebih baik dalam hal ini.[super respondsToSelector:
tidak akan melakukan apa yang Anda inginkan, karena itu sama dengan menelepon[self respondsToSelector:
yang akan kembaliYES
. Yang Anda butuhkan adalah[[ShakingView superclass] instancesRespondToSelector:
.Dari aplikasi Diceshaker saya :
Histeresis mencegah peristiwa guncangan memicu beberapa kali hingga pengguna menghentikan guncangan.
sumber
motionBegan
danmotionEnded
acara tidak terlalu tepat atau akurat dalam hal mendeteksi awal dan akhir goyang. Pendekatan ini memungkinkan Anda untuk menjadi setepat yang Anda inginkan.Saya akhirnya membuatnya bekerja menggunakan contoh kode dari Undo / Redo Manager Tutorial ini .
Inilah yang perlu Anda lakukan:
sumber
applicationSupportsShakeToEdit
adalahYES
.[self resignFirstResponder];
dulu[super viewWillDisappear:animated];
? Ini sepertinya aneh.Pertama, jawaban Kendall tanggal 10 Juli tepat.
Sekarang ... Saya ingin melakukan sesuatu yang serupa (di iPhone OS 3.0+), hanya dalam kasus saya saya menginginkannya di seluruh aplikasi sehingga saya bisa mengingatkan berbagai bagian aplikasi ketika terjadi guncangan. Inilah yang akhirnya saya lakukan.
Pertama, saya subklasifikasi UIWindow . Ini peasy mudah. Buat file kelas baru dengan antarmuka seperti
MotionWindow : UIWindow
(jangan ragu untuk memilih sendiri, natch). Tambahkan metode seperti ini:Ubah
@"DeviceShaken"
ke nama notifikasi pilihan Anda. Simpan file.Sekarang, jika Anda menggunakan MainWindow.xib (stok template kode Xcode), masuk ke sana dan ubah kelas objek Window Anda dari UIWindow ke MotionWindow atau apa pun namanya. Simpan xib. Jika Anda mengatur UIWindow terprogram, gunakan kelas Window baru Anda di sana.
Sekarang aplikasi Anda menggunakan kelas UIWindow khusus . Di mana pun Anda ingin diberi tahu tentang goyangan, daftar untuk pemberitahuan mereka! Seperti ini:
Untuk menghapus diri Anda sebagai pengamat:
Saya menempatkan milik saya di viewWillAppear: dan viewWillDisappear: di mana View Controllers bersangkutan. Pastikan respons Anda terhadap acara goyang tahu apakah itu "sudah dalam proses" atau tidak. Jika tidak, jika perangkat diguncang dua kali berturut-turut, Anda akan mengalami kemacetan lalu lintas. Dengan cara ini Anda dapat mengabaikan notifikasi lain hingga Anda benar-benar selesai merespons notifikasi asli.
Juga: Anda dapat memilih untuk isyarat off dari motionBegan vs motionEnded . Terserah kamu. Dalam kasus saya, efeknya selalu perlu terjadi setelah perangkat dalam keadaan diam (vs. ketika mulai bergetar), jadi saya menggunakan motionEnded . Coba keduanya dan lihat mana yang lebih masuk akal ... atau deteksi / beri tahu untuk keduanya!
Satu lagi pengamatan (penasaran?) Di sini: Perhatikan tidak ada tanda-tanda manajemen responden pertama dalam kode ini. Saya hanya mencoba ini dengan Table View Controllers sejauh ini dan semuanya tampaknya bekerja dengan sangat baik bersama-sama! Saya tidak bisa menjamin skenario lain.
Kendall, et. al - adakah yang bisa berbicara mengapa ini mungkin terjadi untuk subkelas UIWindow ? Apakah karena jendelanya ada di puncak rantai makanan?
sumber
Saya menemukan posting ini mencari implementasi "gemetar". jawaban millenomi bekerja dengan baik untuk saya, walaupun saya sedang mencari sesuatu yang membutuhkan "aksi gemetar" untuk memicu. Saya telah mengganti ke nilai Boolean dengan shakeCount int. Saya juga mengimplementasikan kembali metode L0AccelerationIsShaking () di Objective-C. Anda dapat mengubah jumlah pengocokan yang diperlukan dengan mengubah jumlah yang ditambahkan ke shakeCount. Saya tidak yakin saya telah menemukan nilai optimal, tetapi tampaknya masih berfungsi dengan baik sejauh ini. Semoga ini bisa membantu seseorang:
PS: Saya sudah mengatur interval pembaruan ke 1/15 detik.
sumber
Anda perlu memeriksa accelerometer melalui accelerometer: didAccelerate: metode yang merupakan bagian dari protokol UIAccelerometerDelegate dan periksa apakah nilainya melampaui ambang batas untuk jumlah gerakan yang diperlukan untuk shake.
Ada contoh kode yang layak di accelerometer: didAccelerate: metode tepat di bagian bawah AppController.m dalam contoh GLPaint yang tersedia di situs pengembang iPhone.
sumber
Di iOS 8.3 (mungkin sebelumnya) dengan Swift, sesederhana mengganti metode
motionBegan
ataumotionEnded
di pengontrol tampilan Anda:sumber
Ini adalah kode delegasi dasar yang Anda butuhkan:
Juga atur kode yang sesuai di Interface. yaitu:
@interface MyViewController: UIViewController <UIPickerViewDelegate, UIPickerViewDataSource, UIAccelerometerDelegate>
sumber
Lihatlah contoh GLPaint.
http://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html
sumber
Tambahkan metode berikut dalam file ViewController.m, itu berfungsi dengan baik
sumber
Maaf memposting ini sebagai jawaban daripada komentar tetapi karena Anda dapat melihat saya baru di Stack Overflow dan jadi saya belum cukup terkemuka untuk mengirim komentar!
Pokoknya saya kedua @cire tentang memastikan untuk mengatur status responden pertama setelah tampilan adalah bagian dari hierarki tampilan. Jadi pengaturan status responden pertama dalam
viewDidLoad
metode pengontrol tampilan Anda tidak akan berfungsi misalnya. Dan jika Anda tidak yakin apakah itu berfungsi[view becomeFirstResponder]
mengembalikan boolean yang dapat Anda uji.Poin lain: Anda bisa menggunakan pengontrol tampilan untuk menangkap acara goyang jika Anda tidak ingin membuat subkelas UIView secara tidak perlu. Saya tahu ini tidak terlalu merepotkan tetapi masih ada opsi. Cukup pindahkan cuplikan kode yang dimasukkan Kendall ke dalam subkelas UIView ke dalam pengontrol Anda dan kirim pesan
becomeFirstResponder
danresignFirstResponder
keself
alih-alih subkelas UIView.sumber
Pertama, saya tahu ini adalah posting lama, tetapi masih relevan, dan saya menemukan bahwa dua jawaban pilihan tertinggi tidak mendeteksi guncangan sedini mungkin . Ini adalah cara untuk melakukannya:
Di ViewController Anda:
sumber
Solusi termudah adalah mendapatkan jendela root baru untuk aplikasi Anda:
Kemudian dalam delegasi aplikasi Anda:
Jika Anda menggunakan Storyboard, ini mungkin lebih sulit, saya tidak tahu kode yang akan Anda butuhkan dalam delegasi aplikasi secara tepat.
sumber
@implementation
sejak Xcode 5.Cukup gunakan tiga metode ini untuk melakukannya
untuk perincian Anda dapat memeriksa kode contoh lengkap di sana
sumber
Versi cepat berdasarkan pada jawaban pertama!
sumber
Untuk mengaktifkan aplikasi ini, saya membuat kategori di UIWindow:
sumber