Odpowiedzi:
Z „ Samouczka iPhone'a: lepszy sposób na sprawdzenie możliwości urządzeń iOS ”:
Istnieją dwie pozornie podobne funkcje, które przyjmują parametr kSystemSoundID_Vibrate
:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Obie funkcje wibrują iPhone'a. Ale kiedy używasz pierwszej funkcji na urządzeniach, które nie obsługują wibracji, odtwarza dźwięk. Z drugiej strony druga funkcja nie działa na nieobsługiwanych urządzeniach. Jeśli więc zamierzasz ciągle wibrować urządzeniem, jako ostrzeżenie, zdrowy rozsądek mówi, użyj funkcji 2.
Najpierw dodaj strukturę AudioToolbox AudioToolbox.framework
do celu w Fazach kompilacji.
Następnie zaimportuj ten plik nagłówka:
#import <AudioToolbox/AudioServices.h>
AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))
(przynajmniej od wersji beta 2)
AudioToolbox przedstawia teraz kSystemSoundID_Vibrate
jako SystemSoundID
typ, więc kod jest następujący:
import AudioToolbox.AudioServices
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
Zamiast przechodzić przez dodatkowy etap rzucania
(Rekwizyty do @Dov)
Oto, jak to robisz na Swift (na wypadek, gdybyś miał takie same kłopoty jak ja)
Połącz z AudioToolbox.framework
(Przejdź do projektu, wybierz cel, buduj fazy, Połącz pliki binarne z bibliotekami, dodaj tam bibliotekę)
Po zakończeniu:
import AudioToolbox.AudioServices
// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
Tandetne jest to, że SystemSoundID
jest to po prostu typealias
(fantazyjne szybkie typedef
) dla UInt32
, i kSystemSoundID_Vibrate
jest regularne Int
. Kompilator daje błąd dla próby z obsadą Int
do UInt32
, ale błąd brzmi „nie można przekonwertować do SystemSoundID”, co jest mylące. Dlaczego jabłko po prostu nie sprawiło, że szybki enum jest poza mną.
@ aponomarenko zajmuje się szczegółami, moja odpowiedź dotyczy tylko Swifterów.
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
i skompilowałem się dobrze
Prostym sposobem jest skorzystanie z usług audio:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Miałem z tym duży problem w przypadku urządzeń, które w jakiś sposób wyłączały wibracje, ale potrzebowaliśmy, aby działała niezależnie, ponieważ ma to kluczowe znaczenie dla funkcjonowania naszej aplikacji, a ponieważ jest to tylko liczba całkowita w udokumentowanym wywołaniu metody, przejdzie uprawomocnienie. Więc wypróbowałem kilka dźwięków, które były poza dobrze udokumentowanymi tutaj: TUNER88 / iOSSystemSoundsLibrary
Natknąłem się na 1352, który działa niezależnie od cichego przełącznika lub ustawień urządzenia (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);
}
}
Ważna uwaga: Alert o przyszłej rezygnacji.
Począwszy od iOS 9.0 , opis funkcji API dla:
AudioServicesPlaySystemSound(inSystemSoundID: SystemSoundID)
AudioServicesPlayAlertSound(inSystemSoundID: SystemSoundID)
zawiera następującą notatkę:
This function will be deprecated in a future release.
Use AudioServicesPlayAlertSoundWithCompletion or
AudioServicesPlaySystemSoundWithCompletion instead.
Właściwą drogą będzie użycie jednego z tych dwóch:
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)
lub
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
//your callback code when the vibration is done (it may not vibrate in iPod, but this callback will be always called)
}
Pamiętaj by
import AVFoundation
W przypadku telefonu iPhone 7/7 Plus lub nowszego użyj tych trzech interfejsów API interfejsu Haptic Feedback.
let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)
Dostępne style .error
, .success
i .warning
. Każdy ma swój charakterystyczny charakter.
Z dokumentów :
Konkretna
UIFeedbackGenerator
podklasa, która tworzy dotykową komunikację o sukcesach, niepowodzeniach i ostrzeżeniach.
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()
Dostępne style .heavy
, .medium
i .light
. Są to proste wibracje o różnym stopniu „twardości”.
Z dokumentów :
Konkretna
UIFeedbackGenerator
podklasa, która tworzy dotykową symulację uderzeń fizycznych
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
Jest to najmniej zauważalny ze wszystkich haptików, dlatego jest najbardziej odpowiedni, gdy haptics nie powinien przejmować funkcji aplikacji.
Z dokumentów :
Konkretna
UIFeedbackGenerator
podklasa, która tworzy dotykowe wskazujące zmianę wyboru.
Podczas korzystania z tych interfejsów API warto pamiętać o kilku sprawach.
W rzeczywistości nie tworzysz dotyku. Państwo zażądać system wygenerować dotykowych. System podejmie decyzję w oparciu o poniższe:
Dlatego system po cichu zignoruje twoją prośbę o dotyk, jeśli nie jest to możliwe. Jeśli wynika to z nieobsługiwanego urządzenia, możesz spróbować:
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
}
Zastąp komentarze w instrukcjach switch
- case
, a ten haptyczny kod generowania będzie przenośny na inne urządzenia z systemem iOS. Wygeneruje najwyższy możliwy poziom dotyku.
prepare()
metodę ustawiania go w stan gotowości. Korzystanie z gry Przykład: Możesz wiedzieć, że gra wkrótce się zakończy, ponieważ użytkownik ma bardzo niski poziom zdrowia lub znajduje się w pobliżu niebezpieczny potwór.
W takim przypadku przygotowanie silnika Taptic Engine zapewniłoby lepszą jakość i czułość.
Załóżmy na przykład, że Twoja aplikacja używa rozpoznawania gestów panoramy w celu zmiany widocznej części świata. Chcesz, aby haptik generował się, gdy użytkownik „patrzy” na 360 stopni. Oto jak możesz użyć 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
tej metody. Nie dzwonisz impactOccured
w tej samej instancji, do której dzwonisz prepare
.
A jeśli używasz frameworka Xamarin (monotouch), po prostu zadzwoń
SystemSound.Vibrate.PlayAlertSound()
Podczas moich podróży odkryłem, że jeśli spróbujesz wykonać jedną z poniższych czynności podczas nagrywania dźwięku, urządzenie nie będzie wibrować, nawet jeśli jest włączone.
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Moja metoda została wywołana w określonym czasie przy pomiarze ruchów urządzeń. Musiałem zatrzymać nagrywanie, a następnie uruchomić je ponownie po wystąpieniu wibracji.
Tak to wyglądało.
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder
jest instancją AVRecorder.
Mam nadzieję, że pomoże to innym, którzy mieli wcześniej ten sam problem.
W iOS 10 i nowszych iPhone'ach możesz także używać haptic API. Ta dotykowa informacja zwrotna jest bardziej miękka niż API AudioToolbox.
W przypadku scenariusza GAME OVER odpowiednie informacje zwrotne dotyczące interfejsu użytkownika powinny być odpowiednie.
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
Możesz użyć innych stylów dotykowych .
W moim przypadku korzystałem z AVCaptureSession. AudioToolbox był w fazie kompilacji projektu i został zaimportowany, ale nadal nie działał. Aby to zadziałało, zatrzymałem sesję przed wibracjami i kontynuowałem po niej.
#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];
}
Możesz użyć
1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);
na iPhone'a i kilka nowszych iPodów.
2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
na iPady.