Comment configurer l'iPhone pour qu'il vibre une fois?
Par exemple, lorsqu'un joueur perd une vie ou que le jeu est terminé, l'iPhone devrait vibrer.
De " Tutoriel iPhone: Meilleur moyen de vérifier les capacités des appareils iOS ":
Deux fonctions apparemment similaires prennent un paramètre kSystemSoundID_Vibrate
:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Les deux fonctions font vibrer l'iPhone. Cependant, lorsque vous utilisez la première fonction sur des appareils non compatibles avec les vibrations, un bip retentit. La deuxième fonction, en revanche, ne fait rien sur les appareils non pris en charge. Par conséquent, si vous voulez faire vibrer l'appareil en permanence, utilisez la fonction 2, indique le bon sens.
Tout d’abord, ajoutez le cadre AudioToolbox AudioToolbox.framework
à votre cible dans Build Phases.
Ensuite, importez ce fichier d'en-tête:
#import <AudioToolbox/AudioServices.h>
AudioToolbox présente maintenant le kSystemSoundID_Vibrate
comme un type SystemSoundID
. Le code est donc:
import AudioToolbox.AudioServices
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
Au lieu d'avoir à passer par l'étape de casting supplémentaire
(Accessoires à @Dov)
Et voici comment vous le faites sur Swift (au cas où vous auriez le même problème que moi)
Lien contre AudioToolbox.framework
(Allez à votre projet, sélectionnez votre cible, phases de construction, Lien binaire avec les bibliothèques, ajoutez la bibliothèque là-bas)
Une fois cela terminé:
import AudioToolbox.AudioServices
// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
La chose ringarde est que SystemSoundID
est fondamentalement un typealias
(fantaisie Swift typedef
) pour un UInt32
, et le kSystemSoundID_Vibrate
est un régulier Int
. Le compilateur vous donne une erreur lorsque vous tentez de transtyper de Int
à UInt32
, mais l’erreur indique "Impossible de convertir en SystemSoundID", ce qui prête à confusion. Pourquoi Apple n'a-t-il pas simplement fait en Swift une énumération qui me dépasse?.
@ aponomarenko's va dans les détails, ma réponse est juste pour les Swifters là-bas.
Un moyen simple de le faire est d'utiliser Audio Services:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Cela me posait de gros problèmes pour les périphériques dont les vibrations avaient été désactivées, mais nous devions le faire fonctionner de manière indépendante, car il est essentiel au fonctionnement de notre application et, comme il ne s'agit que d'un entier à un appel de méthode documenté, il passera. validation. J'ai donc essayé quelques sons qui étaient en dehors de ceux bien documentés ici: TUNER88/iOSSystemSoundsLibrary
Je suis ensuite tombé sur 1352, qui fonctionne indépendamment du commutateur silencieux ou des paramètres du périphérique (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);
}
}
Note importante: Alerte de dépréciation future.
À partir de iOS 9., la description des fonctions API pour:
AudioServicesPlaySystemSound(inSystemSoundID: SystemSoundID)
AudioServicesPlayAlertSound(inSystemSoundID: SystemSoundID)
comprend la note suivante:
This function will be deprecated in a future release.
Use AudioServicesPlayAlertSoundWithCompletion or
AudioServicesPlaySystemSoundWithCompletion instead.
La bonne façon d’utiliser l’une de ces deux méthodes est la suivante:
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)
ou
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
//your callback code when the vibration is done (it may not vibrate in iPod, but this callback will be always called)
}
souvenez-vous de
import AVFoundation
Et si vous utilisez le framework Xamarin (monotouch), appelez simplement
SystemSound.Vibrate.PlayAlertSound()
Au cours de mes voyages, j'ai constaté que si vous essayez l'une des opérations suivantes pendant l'enregistrement audio, l'appareil ne vibre pas, même s'il est activé.
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Ma méthode a été appelée à un moment précis dans la mesure des mouvements des appareils. Je devais arrêter l'enregistrement puis le redémarrer après que la vibration se soit produite.
Cela ressemblait à ceci.
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder
est une instance d'AVRecorder.
J'espère que cela aide d'autres personnes qui ont déjà eu le même problème.
Dans iOS 10 et sur les nouveaux iPhones, vous pouvez également utiliser l'API haptique. Ce retour haptique est plus doux que l'API AudioToolbox.
Pour votre scénario GAME OVER, un retour d’impact important de l’UI devrait convenir.
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
Vous pouvez utiliser le autres styles de retour haptique .
Pour un iPhone 7/7 Plus ou plus récent, utilisez ces trois API de retour d'informations Haptic.
let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)
Les styles disponibles sont .error
, .success
et .warning
. Chacun a sa propre sensation distinctive.
Du docs :
Une sous-classe
UIFeedbackGenerator
concrète qui crée une haptique pour communiquer les succès, les échecs et les avertissements.
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()
Les styles disponibles sont .heavy
, .medium
et .light
. Ce sont de simples vibrations avec différents degrés de "dureté".
Du docs :
Une sous-classe
UIFeedbackGenerator
concrète qui crée une haptique pour simuler des impacts physiques
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
C’est le moins perceptible de tous les haptiques, et donc le plus approprié lorsque l’haptique ne devrait pas s’approprier l’expérience de l’application.
Du docs :
Une sous-classe
UIFeedbackGenerator
concrète qui crée une haptique pour indiquer un changement de sélection.
Lorsque vous utilisez ces API, il convient de garder à l’esprit certaines choses qu’il convient de retenir.
Vous ne créez pas réellement l'haptique. Vous demandez au système de générer un haptique. Le système décidera en fonction de ce qui suit:
Par conséquent, le système ignorera votre demande silencieuse si cela n’est pas possible. Si cela est dû à un périphérique non pris en charge, vous pouvez essayer ceci:
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
}
Remplacez les commentaires dans les instructions switch
-case
et ce code de génération haptique sera portable sur d'autres appareils iOS. Cela générera le plus haut niveau possible d'haptique.
prepare()
pour le mettre en état de disponibilité. Exemple d'utilisation de Game Over: Vous savez peut-être que le jeu est sur le point de se terminer, l'utilisateur ayant très peu de HP, ou un monstre dangereux se trouvant à proximité.
Dans ce cas, préparer le moteur Taptic créerait une expérience de meilleure qualité et plus réactive.
Par exemple, supposons que votre application utilise un outil de reconnaissance des gestes panoramiques pour changer la partie du monde visible. Vous souhaitez générer un haptique lorsque l'utilisateur "regarde" à 360 degrés. Voici comment utiliser 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
}
En rapide:
import AVFoundation
...
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
Dans mon cas, j'utilisais AVCaptureSession. AudioToolbox était en phase de construction du projet et il a été importé mais ne fonctionnait toujours pas. Pour que cela fonctionne, j'ai arrêté la session avant vibration et continué après cela.
#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];
}