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 doit vibrer.
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 doit vibrer.
Réponses:
À partir de " Tutoriel iPhone: meilleure façon de vérifier les capacités des appareils iOS ":
Il existe deux fonctions apparemment similaires qui prennent un paramètre kSystemSoundID_Vibrate
:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Les deux fonctions font vibrer l'iPhone. Mais, lorsque vous utilisez la première fonction sur des appareils qui ne prennent pas en charge les vibrations, elle émet un bip. La deuxième fonction, en revanche, ne fait rien sur les appareils non pris en charge. Donc, si vous allez faire vibrer l'appareil en continu, comme une alerte, le bon sens dit, utilisez la fonction 2.
Tout d'abord, ajoutez le framework AudioToolbox AudioToolbox.framework
à votre cible dans Build Phases.
Ensuite, importez ce fichier d'en-tête:
#import <AudioToolbox/AudioServices.h>
AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))
(au moins à partir de la bêta 2)
AudioToolbox présente maintenant le kSystemSoundID_Vibrate
comme un SystemSoundID
type, donc le code est:
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 rencontré le même problème que moi)
Lier contre AudioToolbox.framework
(Accédez à votre projet, sélectionnez votre cible, phases de construction, Liez le binaire aux bibliothèques, ajoutez-y la bibliothèque)
Une fois cela terminé:
import AudioToolbox.AudioServices
// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
Ce qui SystemSoundID
est ringard, c'est que c'est fondamentalement un typealias
(fantaisie rapide typedef
) pour un UInt32
, et kSystemSoundID_Vibrate
c'est un habitué Int
. Le compilateur vous donne une erreur pour essayer de caster de Int
versUInt32
convertir , mais l'erreur se lit comme "Impossible de convertir en SystemSoundID", ce qui est déroutant. Pourquoi Apple n'a-t-il pas simplement fait d'enum Swift est au-delà de moi.
@ aponomarenko va dans les détails, ma réponse est juste pour les Swifters là-bas.
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
et cela s'est bien compilé
Un moyen simple de le faire est avec les services audio:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
J'ai eu de gros problèmes avec cela pour les appareils dont les vibrations étaient désactivées d'une manière ou d'une autre, mais nous en avions besoin pour fonctionner malgré tout, car cela est essentiel au fonctionnement de notre application, et comme il ne s'agit que d'un entier pour 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
J'ai ensuite trébuché sur 1352, qui fonctionne indépendamment du commutateur silencieux ou des paramètres de l'appareil (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);
}
}
Remarque importante: Alerte de dépréciation future.
Depuis iOS 9.0 , la description des fonctions de l' 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 de procéder sera d'utiliser l'un de ces deux éléments:
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)
}
se souvenir de
import AVFoundation
Pour un iPhone 7/7 Plus ou plus récent, utilisez ces trois API de rétroaction Haptic.
let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)
Sont styles disponibles .error
, .success
et .warning
. Chacun a sa propre sensation distinctive.
De la documentation :
Une
UIFeedbackGenerator
sous-classe concrète qui crée des haptiques pour communiquer les succès, les échecs et les avertissements.
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()
Sont styles disponibles .heavy
, .medium
et .light
. Ce sont de simples vibrations avec différents degrés de "dureté".
De la documentation :
Une
UIFeedbackGenerator
sous-classe concrète qui crée des haptiques pour simuler les impacts physiques
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
C'est le moins perceptible de tous les haptiques, et donc le plus approprié lorsque les haptiques ne devraient pas prendre le contrôle de l'expérience de l'application.
De la documentation :
Une
UIFeedbackGenerator
sous-classe concrète qui crée des haptiques pour indiquer un changement de sélection.
Il y a quelques points à retenir lors de l'utilisation de ces API.
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 silencieusement votre demande d'haptique 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
}
Remplacer les commentaires dans le switch
-case
instructions , et ce code de génération haptique sera portable sur d'autres appareils iOS. Il générera le plus haut niveau d'haptique possible.
prepare()
méthode pour la mettre en état de préparation. Utilisation de votre exemple Game Over: vous savez peut-être que le jeu est sur le point de se terminer, si l'utilisateur a des PV très bas ou qu'un monstre dangereux est près d'eux.
Dans ce cas, la préparation du Taptic Engine créerait une expérience de meilleure qualité et plus réactive.
Par exemple, supposons que votre application utilise un identificateur de mouvement panoramique pour modifier la partie du monde visible. Vous souhaitez générer un haptique lorsque l'utilisateur «regarde» à 360 degrés. Voici comment vous pouvez 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
}
import UIKit
!
haptic
intérieur de cette méthode. Vous impactOccured
n'appelez pas sur la même instance que vous appelez prepare
.
Au cours de mes voyages, j'ai constaté que si vous essayez l'une des options suivantes pendant que vous enregistrez de l'audio, l'appareil ne vibrera 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. J'ai dû arrêter l'enregistrement, puis le redémarrer après la vibration.
Cela ressemblait à ça.
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder
est une instance 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 iPhones plus récents, vous pouvez également utiliser l'API haptique. Cette rétroaction haptique est plus douce que l'API AudioToolbox.
Pour votre scénario GAME OVER, une rétroaction d'impact sur l'interface utilisateur lourde devrait convenir.
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
Vous pouvez utiliser les autres styles de rétroaction haptique .
Dans mon cas, j'utilisais l'AVCaptureSession. AudioToolbox était en phase de construction du projet et il a été importé mais ne fonctionnait toujours pas. Afin de le faire fonctionner, j'ai arrêté la session avant les vibrations et j'ai continué après.
#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];
}
Vous pouvez utiliser
1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);
pour iPhone et quelques iPods plus récents.
2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
pour iPad.