Membuat iPhone bergetar


228

Bagaimana iPhone dapat diatur agar bergetar sekali?

Misalnya, ketika seorang pemain kehilangan nyawa atau permainan berakhir, iPhone harus bergetar.


9
Gerakan goyang sama sekali berbeda dari getaran. Satu diprakarsai oleh manusia, satu diprakarsai oleh perangkat.
Eiko

Jawaban:


404

Dari " Tutorial iPhone: Cara yang lebih baik untuk memeriksa kemampuan perangkat iOS ":

Ada dua fungsi yang tampaknya serupa yang mengambil parameter kSystemSoundID_Vibrate:

1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Kedua fungsi tersebut menggetarkan iPhone. Tetapi, ketika Anda menggunakan fungsi pertama pada perangkat yang tidak mendukung getaran, ia memainkan suara bip. Fungsi kedua, di sisi lain, tidak melakukan apa pun pada perangkat yang tidak didukung. Jadi jika Anda akan menggetarkan perangkat secara terus menerus, sebagai peringatan, kata akal sehat, gunakan fungsi 2.

Pertama, tambahkan kerangka AudioToolbox AudioToolbox.frameworkke target Anda di Build Phases.

Kemudian, impor file header ini:

#import <AudioToolbox/AudioServices.h>

3
#import <Cocoa / Cocoa.h> tidak diperlukan.
Raptor

10
Apakah ada cara untuk mengurangi waktu getaran menjadi kurang dari 1 detik?
George Asda

11
Saya ingin menambahkan, bahwa jika getaran tidak aktif di Pengaturan iOS, pengguna tidak akan mendapatkan getaran bahkan jika Anda menggunakan perintah ini.
Denis Kutlubaev

7
In Swift: AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))(setidaknya pada beta 2)
Sam Soffes

1
AudioServicesPlayAlertSound (kSystemSoundID_Vibrate); Getar pada iPhone dengan benar tetapi tidak membuat suara bip pada iPad.
Mangesh

45

Swift 2.0+

AudioToolbox sekarang menyajikan kSystemSoundID_Vibratesebagai SystemSoundIDtipe, jadi kodenya adalah:

import AudioToolbox.AudioServices

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

Daripada harus melalui langkah pemeran tambahan

(Alat Peraga ke @Dov)

Jawaban Asli (Swift 1.x)

Dan, inilah cara Anda melakukannya di Swift (jika Anda mengalami masalah yang sama dengan saya)

Tautan melawan AudioToolbox.framework(Buka proyek Anda, pilih target Anda, bangun fase, Tautan Biner dengan Perpustakaan, tambahkan perpustakaan di sana)

Setelah selesai:

import AudioToolbox.AudioServices

// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))

Yang murahan adalah bahwa SystemSoundIDpada dasarnya adalah typealias(suka cepat typedef) untuk UInt32, dan itu kSystemSoundID_Vibrateadalah biasa Int. Compiler memberikan Anda sebuah kesalahan untuk mencoba pemain dari Intke UInt32, tapi kesalahan berbunyi sebagai "Tidak bisa dikonversi ke SystemSoundID", yang membingungkan. Mengapa apel tidak membuatnya menjadi Swift enum ada di luar jangkauan saya.

@ aponomarenko masuk ke rincian, jawaban saya hanya untuk Swifters di luar sana.


Ini tampaknya diperbaiki di Swift 2 / iOS 9 / Xcode 7. Saya menggunakan AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)dan dikompilasi dengan baik
Dov

35

Cara mudah untuk melakukannya adalah dengan Layanan Audio:

#import <AudioToolbox/AudioToolbox.h> 
...    
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

3
#import <AudioToolbox / AudioToolbox.h> dan Anda harus menambahkan AudioToolbox.framework ke Fase Bangun proyek Anda.
Michael Mangold

31

Saya mempunyai masalah besar dengan ini untuk perangkat yang getarannya dimatikan dalam beberapa cara, tetapi kami membutuhkannya untuk bekerja terlepas, karena sangat penting untuk fungsi aplikasi kami, dan karena itu hanya bilangan bulat untuk pemanggilan metode yang didokumentasikan, itu akan lulus validasi. Jadi saya telah mencoba beberapa suara di luar yang terdokumentasi dengan baik di sini: TUNER88 / iOSSystemSoundsLibrary

Saya kemudian menemukan 1352, yang berfungsi terlepas dari saklar diam atau pengaturan pada perangkat (Settings->vibrate on ring, vibrate on silent).

- (void)vibratePhone;
{
     if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
     {
         AudioServicesPlaySystemSound (1352); //works ALWAYS as of this post
     }
     else
     {
          // Not an iPhone, so doesn't have vibrate
          // play the less annoying tick noise or one of your own
          AudioServicesPlayAlertSound (1105);
     }
}

7
Itu selalu lebih baik untuk menggunakan alias bernama daripada konstanta sihir, seperti kSystemSoundID_Vibrate sebagai gantinya 1352. Saya mendorong Anda untuk memperbarui jawaban Anda.
nalexn

3
Saya setuju menggunakan sihir 1352 ini tidak ideal, tetapi saya tidak dapat menemukan cara lain untuk memaksa getaran bahkan ketika sakelar getar mati pada perangkat. Ini sepertinya satu-satunya cara.
marcshilling

4
Saya menulis for for dengan bilangan bulat mulai dari konstanta yang diterbitkan dan mencari tahu mana yang menyebabkan getaran
Joel Teply

2
Saya dapat mengonfirmasi bahwa iPhone bergetar meskipun mode diam diaktifkan pada iPhone. Jawaban bagus!
vomako

2
AudioServicesPlaySystemSound (1352) masih berfungsi untuk iPhone terlepas dari posisi sakelar senyap pada Jan 2016
JustAnotherCoder

26

Catatan Penting: Peringatan Penghentian Masa Depan.

Pada iOS 9.0 , deskripsi fungsi API untuk:

AudioServicesPlaySystemSound(inSystemSoundID: SystemSoundID)
AudioServicesPlayAlertSound(inSystemSoundID: SystemSoundID)

termasuk catatan berikut:

This function will be deprecated in a future release.
Use AudioServicesPlayAlertSoundWithCompletion or  
AudioServicesPlaySystemSoundWithCompletion instead.

Cara yang tepat untuk menggunakan salah satu dari dua ini:

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)

atau

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
 //your callback code when the vibration is done (it may not vibrate in iPod, but this callback will be always called)
}

ingat untuk import AVFoundation


Anda melewatkan pernyataan impor
Juan Boero

import AudioToolbox.AudioServices
Hugo Alonso

saya melakukannya sendiri, hanya dengan AVFoundation.
Juan Boero

Pokoknya mengatur durasi getaran?
Mikro

Anda perlu menggabungkan beberapa panggilan, menggunakan selang waktu di antara setiap panggilan baru
Hugo Alonso

7

Untuk iPhone 7/7 Plus atau lebih baru, gunakan tiga API umpan balik Haptic ini.

API yang tersedia

Untuk pemberitahuan:

let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)

Gaya yang tersedia adalah .error, .success, dan .warning. Masing-masing memiliki nuansa tersendiri.
Dari dokumen :

UIFeedbackGeneratorSubkelas konkret yang menciptakan haptics untuk mengomunikasikan keberhasilan, kegagalan, dan peringatan.

Untuk getaran sederhana:

let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()

Gaya yang tersedia adalah .heavy, .medium, dan .light. Ini adalah getaran sederhana dengan berbagai tingkat "kekerasan".
Dari dokumen :

UIFeedbackGeneratorSubkelas konkret yang menciptakan haptics untuk mensimulasikan dampak fisik

Untuk saat pengguna memilih item

let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()

Ini adalah yang paling tidak terlihat dari semua haptics, dan juga yang paling cocok untuk saat haptics tidak boleh mengambil alih pengalaman aplikasi.
Dari dokumen :

UIFeedbackGeneratorSubkelas konkret yang membuat haptics untuk mengindikasikan perubahan dalam pemilihan.

Catatan

Ada beberapa hal yang perlu diingat ketika menggunakan API ini.

Catatan A

Anda sebenarnya tidak membuat haptic. Anda meminta sistem menghasilkan haptic. Sistem akan memutuskan berdasarkan hal-hal berikut:

  • Jika haptics dimungkinkan pada perangkat (apakah memiliki Mesin Taptic dalam kasus ini)
  • Apakah aplikasi dapat merekam audio (haptics tidak menghasilkan selama perekaman untuk mencegah gangguan yang tidak diinginkan)
  • Apakah haptics diaktifkan di Pengaturan sistem.

Karena itu, sistem akan secara diam-diam mengabaikan permintaan Anda akan haptic jika itu tidak mungkin. Jika ini disebabkan oleh perangkat yang tidak didukung, Anda dapat mencoba ini:

func haptic() {
    // Get whether the device can generate haptics or not
    // If feedbackSupportLevel is nil, will assign 0
    let feedbackSupportLevel = UIDevice.current.value(forKey: "_feedbackSupportLevel") as? Int ?? 0

    switch feedbackSupportLevel { 
    case 2:
        // 2 means the device has a Taptic Engine
        // Put Taptic Engine code here, using the APIs explained above

    case 1: 
    // 1 means no Taptic Engine, but will support AudioToolbox
    // AudioToolbox code from the myriad of other answers!

    default: // 0
        // No haptic support
        // Do something else, like a beeping noise or LED flash instead of haptics
    }

Ganti komentar dalam switch- casepernyataan, dan kode generasi haptic ini akan portabel untuk perangkat iOS lainnya. Ini akan menghasilkan tingkat haptic tertinggi.

Catatan B

  • Karena fakta bahwa menghasilkan haptics adalah tugas tingkat hardware , mungkin ada latensi antara ketika Anda memanggil kode generasi haptic, dan ketika itu benar - benar terjadi. Karena alasan ini, Taptic Engine APIs semuanya memiliki prepare()metode, untuk membuatnya siap. Menggunakan Game Anda Sebagai contoh: Anda mungkin tahu bahwa game ini akan berakhir, oleh pengguna yang memiliki HP sangat rendah, atau monster berbahaya berada di dekat mereka.
  • Jika Anda tidak menghasilkan haptic dalam beberapa detik, Mesin Taptic akan kembali ke kondisi siaga (untuk menghemat masa pakai baterai)


Dalam hal ini, mempersiapkan Mesin Taptic akan menciptakan pengalaman yang lebih berkualitas dan lebih responsif.

Sebagai contoh, katakanlah aplikasi Anda menggunakan recogniser gerakan panci untuk mengubah bagian dunia yang terlihat. Anda ingin haptic dihasilkan ketika pengguna 'terlihat' bulat 360 derajat. Inilah cara Anda dapat menggunakan prepare():

@IBAction func userChangedViewablePortionOfWorld(_ gesture: UIPanGestureRecogniser!) {

    haptic = UIImpactFeedbackGenerator(style: .heavy)

    switch gesture.state {
        case .began:
            // The user started dragging the screen.
            haptic.prepare()

        case .changed:
            // The user trying to 'look' in another direction
            // Code to change viewable portion of the virtual world

            if virtualWorldViewpointDegreeMiddle = 360.0 { 
                haptic.impactOccured()
            }
        
        default:
            break

} 

Ingatlah untuk import UIKit!
Benj

Anda tidak ingin membuat instance baru hapticdi dalam metode ini. Anda tidak memanggil impactOccuredpada contoh yang sama yang Anda panggil prepare.
rmaddy

5

Dan jika Anda menggunakan kerangka Xamarin (monotouch), cukup telepon

SystemSound.Vibrate.PlayAlertSound()

5

Dalam perjalanan saya, saya telah menemukan bahwa jika Anda mencoba salah satu dari yang berikut saat Anda merekam audio, perangkat tidak akan bergetar meskipun diaktifkan.

1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Metode saya dipanggil pada waktu tertentu dalam pengukuran gerakan perangkat. Saya harus menghentikan rekaman dan kemudian memulai kembali setelah getaran terjadi.

Terlihat seperti ini.

-(void)vibrate {
    [recorder stop];
    AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
    [recorder start];
}

recorder adalah instance AVRecorder.

Semoga ini bisa membantu orang lain yang memiliki masalah yang sama sebelumnya.


4

Di iOS 10, dan pada iPhone yang lebih baru, Anda juga dapat menggunakan API haptic. Umpan balik haptic ini lebih lunak daripada AudioToolbox API.

Untuk skenario GAME OVER Anda, umpan balik dampak UI yang berat harus cocok.

UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

Anda dapat menggunakan gaya umpan balik haptic lainnya .


1

Dalam Swift:

import AVFoundation
...
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))

0

Dalam kasus saya, saya menggunakan AVCaptureSession. AudioToolbox sedang dalam fase pembangunan proyek dan itu diimpor tetapi masih tidak berfungsi. Untuk membuatnya berfungsi, saya menghentikan sesi sebelum getaran dan melanjutkan setelah itu.

#import <AudioToolbox/AudioToolbox.h>
...
@property (nonatomic) AVCaptureSession *session;
...
- (void)vibratePhone;
{
  [self.session stopRunning];
     NSLog(@"vibratePhone %@",@"here");
    if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
    {
        AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); 
    }
    else
    {
        AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);
    }
  [self.session startRunning];
}

-5

Kamu bisa memakai

1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);

untuk iPhone dan beberapa iPod yang lebih baru.

2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

untuk iPad.


3
iPod touch dan iPad tidak dapat bergetar.
DDPWNAGE

1
pada perangkat tanpa kemampuan getaran (seperti iPod Touch) ini tidak akan melakukan apa pun
Lal Krishna
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.