Заставить 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>
linuxbuild
источник
3
#import <Cocoa / Cocoa.h> не требуется.
Raptor
10
Есть ли способ уменьшить время вибрации до 1 с?
Джордж Асда
11
Я хотел бы добавить, что если в настройках iOS отключена вибрация, пользователь не получит вибрации, даже если вы используете эти команды.
Денис Кутлубаев
7
В Swift: AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))(по крайней мере, в бета-версии 2)
Сэм Соффс
1
AudioServicesPlayAlertSound (kSystemSoundID_Vibrate); Вибрируйте на iPhone, но он не издает никаких звуковых сигналов на iPad.
Мангеш,
45

Swift 2.0+

AudioToolbox теперь представлен kSystemSoundID_Vibrateкак SystemSoundIDтип, поэтому код:

import AudioToolbox.AudioServices

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

Вместо того, чтобы идти через дополнительный шаг броска

(Реквизит @Dov)

Оригинальный ответ (Swift 1.x)

И вот как вы делаете это на Swift (на случай, если вы столкнулись с той же проблемой, что и я)

Ссылка на AudioToolbox.framework(перейдите к своему проекту, выберите цель, этапы сборки, Link Binary with Libraries, добавьте туда библиотеку)

Как только это будет завершено:

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», что приводит к путанице. Почему яблоко просто не сделало его быстрым перечислением вне меня.

@ aponomarenko в деталях, мой ответ только для Swifters там.

Жестяная банка
источник
Это, кажется, исправлено в Swift 2 / iOS 9 / Xcode 7. Я использовал, AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)и он прекрасно скомпилирован
Dov
35

Простой способ сделать это с помощью Audio Services:

#import <AudioToolbox/AudioToolbox.h> 
...    
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
fsaint
источник
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 не идеально, но я не могу найти какой-либо другой способ вызвать вибрацию, даже если выключатель вибрации выключен на устройстве. Кажется, это единственный путь.
Marcshilling
4
Я написал цикл for с целыми числами, начинающимися после опубликованных констант, и выяснил, какая из них вызывает вибрацию
Джоэл Тепли
2
Я могу подтвердить, что iPhone вибрирует, даже если на iPhone активирован беззвучный режим. Отличный ответ!
Vomako
2
AudioServicesPlaySystemSound (1352) по-прежнему работает для iPhone независимо от положения тихого переключателя по состоянию на январь 2016 года
JustAnotherCoder
26

Важное примечание: предупреждение об устаревании в будущем.

Начиная с iOS 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

Хьюго Алонсо
источник
Вы пропустили заявление на импорт
Хуан Боэро
импорт 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. Это создаст самый высокий уровень тактильной возможной.

Примечание Б

  • В связи с тем, что генерация тактильных файлов является задачей аппаратного уровня , может возникнуть задержка между вызовом кода генерации тактового кода и его фактическим выполнением. По этой причине все API-интерфейсы Taptic Engine имеют prepare()метод для перевода его в состояние готовности. Используя пример Game Over: вы можете знать, что игра заканчивается, потому что у пользователя очень низкий уровень здоровья или рядом с ними опасный монстр.
  • Если вы не генерируете тактильный сигнал в течение нескольких секунд, 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

} 
Benj
источник
Просто не забудьте import UIKit!
Benj
Вы не хотите создавать новый экземпляр hapticвнутри этого метода. Вы не вызываете impactOccuredтот же экземпляр, который вызываете prepare.
rmaddy
5

И если вы используете фреймворк Xamarin (monotouch), просто позвоните

SystemSound.Vibrate.PlayAlertSound()
Wheelie
источник
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. Эта тактильная обратная связь мягче, чем AudioToolbox API.

Для вашего сценария GAME OVER должна подойти сильная обратная связь с UI.

UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

Вы можете использовать другие тактильные стили обратной связи .

samwize
источник
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];
}
Caner Çakmak
источник
-5

Ты можешь использовать

1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);

для iPhone и нескольких новых iPod.

2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

для iPad.

сват кришнан
источник
3
iPod касается, и iPad не может вибрировать.
DDPWNAGE
1
на устройстве без вибрационной способности (например, iPod Touch) это ничего не даст
Лал Кришна