Змушує iPhone вібрувати


228

Як iPhone може налаштувати вібрувати один раз?

Наприклад, коли гравець втрачає життя або гра закінчена, iPhone повинен вібрувати.


9
Жест тремтіння зовсім інший, ніж вібрація. Один - ініційований людиною, один - ініційований пристроєм.
Ейко

Відповіді:


404

З " Підручника iPhone: Кращий спосіб перевірити можливості пристроїв iOS ":

Є дві, здавалося б, подібні функції, які приймають параметр kSystemSoundID_Vibrate:

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

Обидві функції вібрують iPhone. Але коли ви використовуєте першу функцію на пристроях, які не підтримують вібрацію, вона відтворює звуковий сигнал. Друга функція, з іншого боку, нічого не робить на непідтримуваних пристроях. Тож якщо ви збираєтеся вібрувати пристрій постійно, як стверджує здоровий глузд, використовуйте функцію 2.

По-перше, додайте рамку AudioToolbox AudioToolbox.frameworkдо своєї цілі у фазах збірки.

Потім імпортуйте цей файл заголовка:

#import <AudioToolbox/AudioServices.h>

3
#import <Какао / Какао.h> не потрібно.
Раптор

10
Чи є спосіб зменшити час вібрації до менш ніж 1 секунди?
Джордж Асда

11
Я хотів би додати, що якщо вібрація вимкнена в налаштуваннях iOS, користувач не отримає вібрацію, навіть якщо ви будете використовувати ці команди.
Денис Кутлубаєв

7
У Свіфті: AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))(принаймні, у бета-версії 2)
Сем Соффс

1
AudioServicesPlayAlertSound (kSystemSoundID_Vibrate); Вібруйте на iPhone, але він не видає звукового сигналу на iPad.
Менгеш

45

Швидкий 2.0+

Тепер AudioToolbox представляє kSystemSoundID_Vibrateяк SystemSoundIDтип, так що код:

import AudioToolbox.AudioServices

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

Замість того, щоб пройти через додатковий крок в ролях

(Реквізити до @Dov)

Оригінальний відповідь (Швидкий 1.x)

І ось, як ви це робите на Свіфті (якщо ви зіткнулися з тією ж проблемою, що і я)

Посилання проти AudioToolbox.framework(Перейдіть до свого проекту, виберіть ціль, складіть фази, зв’яжіть бінарне з бібліотеками, додайте туди бібліотеку)

Як тільки це буде завершено:

import AudioToolbox.AudioServices

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

Сирна річ полягає в тому, що SystemSoundIDв основному є typealias(фантазійний стрімкий typedef) для UInt32, і kSystemSoundID_Vibrateце регулярно Int. Компілятор дає помилку за спробу кидка від Intдо UInt32, але помилка читається як «не вдається перетворити в SystemSoundID», який збиває з пантелику. Чому яблуко просто не зробило його перерахунком Свіфта.

@ апономаренко вникає в деталі, моя відповідь - саме для Swifters там.


Це, здається, виправлено у Swift 2 / iOS 9 / Xcode 7. Я використовував, AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)і це добре складено
Dov

35

Простий спосіб зробити це за допомогою аудіопослуг:

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

3
#import <AudioToolbox / AudioToolbox.h>, і вам потрібно буде додати AudioToolbox.framework до фаз збірки проекту.
Майкл Мангольд

31

У мене виникли великі проблеми з цим пристроями, у яких вібрація якимось чином відключилася, але нам це було потрібно для роботи незалежно, оскільки це важливо для функціонування нашої програми, і оскільки це лише ціле число для документально виклику методу, воно пройде перевірка. Тож я спробував деякі звуки, які були поза добре задокументованими тут: TUNER88 / iOSSystemSoundsLibrary

Потім я натрапив на 1352, який працює незалежно від беззвучного перемикача чи налаштувань на пристрої (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
Завжди краще використовувати названі псевдоніми замість магічних констант, наприклад kSystemSoundID_Vibrate замість 1352. Я рекомендую оновити свою відповідь.
nalexn

3
Я погодився б використовувати цю магію 1352 не ідеально, але я не можу знайти іншого способу примусити вібрацію, навіть коли вимикач вимкнено на пристрої. Це здається єдиним способом.
маркшилінг

4
Я написав цикл для цілих чисел, починаючи повз опубліковані константи, і з'ясував, яка з них викликала вібрацію
Джоел Теплі

2
Я можу підтвердити, що iPhone вібрує, навіть якщо на iPhone ввімкнено безшумний режим. Чудова відповідь!
vomako

2
AudioServicesPlaySystemSound (1352) як і раніше працює для iPhone, незалежно від положення беззвучного перемикання станом на січень 2016
JustAbodyCoder

26

Важлива примітка: Попередження про майбутнє застарівання.

З прошивкою 9.0 , то API Опис функцій для:

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

включає таку примітку:

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

Правильним шляхом буде використання будь-якого з цих двох:

AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)

або

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

пам'ятати import AVFoundation


ви пропускаєте заяву про імпорт
Juan Boero

імпортувати AudioToolbox.AudioServices
Уго Алонсо

Я це робив сам, якраз із AVFoundation.
Хуан Боеро

У будь-якому випадку встановити тривалість вібрації?
Мікро

Вам потрібно буде об'єднати кілька дзвінків, використовувати проміжок часу між кожним новим дзвінком
Уго Алонсо

7

Для iPhone 7/7 Plus або новішої версії використовуйте ці три API-зв’язки Haptic.

Доступні API

Для сповіщень:

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

Доступні стилі .error, .successі .warning. У кожного своє своєрідне відчуття.
З документів :

Конкретний UIFeedbackGeneratorпідклас, який створює хаптики для повідомлення про успіхи, невдачі та попередження.

Для простих вібрацій:

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

Доступні стилі .heavy, .mediumі .light. Це прості вібрації з різним ступенем "твердості".
З документів :

Конкретний UIFeedbackGeneratorпідклас, який створює хаптики для імітації фізичних впливів

Бо коли користувач вибрав предмет

let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()

Це найменш помітно з усіх хаптиків, і тому воно є найбільш підходящим для тих випадків, коли хаптики не повинні переймати досвід роботи з додатком.
З документів :

Конкретний UIFeedbackGeneratorпідклас, який створює хаптики для вказівки на зміну вибору.

Примітки

Є кілька речей, про які варто пам’ятати, використовуючи ці API.

Примітка А

Ви насправді не створюєте гаптика. Ви вимагаєте, щоб система генерувала тактику. Система вирішить, виходячи з наведеного нижче:

  • Якщо на пристрої можливі хаптики (чи є в цьому випадку Taptic Engine)
  • Чи може програма записувати аудіо (хаптики не створюються під час запису для запобігання небажаних втручань)
  • Чи ввімкнено хаптики в налаштуваннях системи.

Тому система мовчки проігнорує ваш запит на випадок, якщо це неможливо. Якщо це пов’язано з непідтримуваним пристроєм, ви можете спробувати це:

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
    }

Замініть коментарі у твердженнях switch- case, і цей кодовий код генерації буде переносним на інші пристрої iOS. Це призведе до найвищого можливого рівня гаптики.

Примітка B

  • Через те, що генерація хаптиків є завданням на рівні апаратних засобів , може виникнути затримка між тим, коли ви викликаєте код генерації тактичних даних, і коли це відбувається насправді. З цієї причини в API API Taptic Engine є prepare()метод, який дозволяє привести його в стан готовності. Використання прикладу Game Over: Ви можете знати, що гра вже закінчиться, якщо користувач має дуже низький рівень HP, або небезпечний монстр знаходиться поруч з ними.
  • Якщо протягом декількох секунд ви не генеруєте тактику, Taptic Engine повернеться в неробочий стан (щоб заощадити час автономної роботи)


У цьому випадку підготовка Taptic Engine створила б якісніший та чутливіший досвід.

Наприклад, скажімо, що ваш додаток використовує розпізнавальник жестів, щоб змінити видиму частину світу. Ви хочете генерувати хапси, коли користувач "виглядає" круглими 360 градусами. Ось як можна використовувати 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!
Benj

Ви не хочете створювати новий екземпляр hapticвсередині цього методу. Ви не impactOccuredдзвоните в той самий екземпляр, що і ви prepare.
rmaddy

5

А якщо ви використовуєте рамку Xamarin (monotouch), просто зателефонуйте

SystemSound.Vibrate.PlayAlertSound()

5

Під час своїх подорожей я виявив, що якщо ви спробуєте будь-що з наступного, поки ви записуєте аудіо, пристрій не вібруватиме, навіть якщо він включений.

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

Мій метод був викликаний у певний час при вимірюванні руху пристроїв. Мені довелося припинити запис, а потім перезапустити його після появи вібрації.

Це виглядало так.

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

recorder є екземпляром AVRecorder.

Сподіваюсь, це допомагає іншим, у кого раніше були ті самі проблеми.


4

В iOS 10 та новіших iPhone можна також використовувати API-тактику. Цей гаптичний зворотний зв'язок м'якший, ніж API AudioToolbox.

Для вашого сценарію GAME OVER слід підходити з високим ступенем зворотного зв’язку з інтерфейсом.

UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

Ви можете використовувати інші стилі зворотного зв'язку .


1

У Свіфті:

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

0

У моєму випадку я використовував AVCaptureSession. AudioToolbox був у фазі збирання проекту, і він був імпортований, але все ще не працював. Для того, щоб він працював, я припинив сеанс перед вібрацією і продовжував продовжувати.

#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

Можна використовувати

1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);

для iPhone та декількох новіших iPod.

2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

для iPad.


3
iPod touch та iPad не можуть вібрувати.
DDPWNAGE

1
на пристрої без вібрації (наприклад, iPod Touch) це нічого не зробить
Лал Кришна
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.