Заставить iPhone вибрировать - PullRequest
224 голосов
/ 18 января 2011

Как настроить iPhone на вибрацию один раз?

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

Ответы [ 12 ]

398 голосов
/ 18 января 2011

Из " iPhone Tutorial: лучший способ проверить возможности устройств iOS ":

Есть две, казалось бы, похожие функции, которые принимают параметр kSystemSoundID_Vibrate:

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

Обе функции вибрируют на iPhone. Но когда вы используете первый функция на устройствах, которые не поддерживают вибрацию, она подает звуковой сигнал звук. Вторая функция, с другой стороны, ничего не делает на неподдерживаемые устройства. Так что если вы собираетесь вибрировать устройство постоянно, как говорит здравый смысл, используйте функцию 2.

Сначала добавьте инфраструктуру AudioToolbox AudioToolbox.framework к своей цели в Фазах сборки.

Затем импортируйте этот заголовочный файл:

#import <AudioToolbox/AudioServices.h>
45 голосов
/ 29 сентября 2014

Swift 2.0 +

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

import AudioToolbox.AudioServices

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

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

(Проповеди на @Dov)

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

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

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

@ aponomarenko подробно расскажет, мой ответ только для Swifters там.

35 голосов
/ 18 января 2011

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

#import <AudioToolbox/AudioToolbox.h> 
...    
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
28 голосов
/ 03 апреля 2014

У меня были большие проблемы с этим для устройств, которые каким-то образом отключили вибрацию, но нам нужно было, чтобы она работала независимо, потому что это критично для функционирования нашего приложения, и поскольку это просто целое число для документированного вызова метода,это пройдет проверку.Итак, я попробовал некоторые звуки, которые были за пределами хорошо документированных здесь: 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);
     }
}
24 голосов
/ 08 октября 2015

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

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

5 голосов
/ 20 ноября 2013

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

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

Мой метод был вызван по определенному адресувремя при измерении движения приборов.Мне пришлось остановить запись, а затем перезапустить ее после возникновения вибрации.

Это выглядело так.

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

recorder - это экземпляр AVRecorder.

Надеюсь, что это поможет другим, у которых раньше была такая же проблема.

5 голосов
/ 29 октября 2013

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

SystemSound.Vibrate.PlayAlertSound()
4 голосов
/ 30 апреля 2018

В iOS 10 и на более новых iPhone вы также можете использовать тактильный API.Эта тактильная обратная связь мягче, чем у AudioToolbox API.

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

UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

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

3 голосов
/ 02 мая 2019

Для 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, который создает тактильные ощущения для имитации физических воздействий

Когда пользователь выбралitem

let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()

Это наименее заметный из всех тактильных ощущений, и поэтому он наиболее подходит для случаев, когда тактильные гаджеты не должны воспринимать опыт приложения.
Из документов :

Конкретный подкласс UIFeedbackGenerator, который создает тактильные детали для указания изменения в выборе.

Примечания

Есть несколько моментов, которые стоит запомнить при использовании этих API.

Примечание A

Вы на самом деле не создаете тактильный. Вы запроссистема генерирует тактильную тактику.Система решит, основываясь на следующем:

  • Если возможны неприятные ощущения на устройстве (имеет ли он в данном случае 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

  • Из-за того, что генерация тактильных сигналов является задачей hardware , может возникнутьзадержка между тем, когда вы вызываете код тактильной генерации, и когда он действительно происходит. По этой причине все 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

} 
1 голос
/ 07 августа 2015

В Свифт:

import AVFoundation
...
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...