使iPhone震动


228

如何将iPhone设置为振动一次?

例如,当玩家丧生或游戏结束时,iPhone应该振动。


9
摇动手势与振动完全不同。一种是人为启动的,一种是设备启动的。
Eiko

Answers:


404

从“ iPhone教程:检查iOS设备功能的更好方法 ”开始:

有两个看似相似的函数带有一个参数kSystemSoundID_Vibrate

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

这两个功能都使iPhone震动。但是,当您在不支持振动的设备上使用第一个功能时,它会发出蜂鸣声。另一方面,第二个功能在不受支持的设备上不执行任何操作。因此,如果您要连续振动设备,如常识所说,作为警报,请使用功能2。

首先,AudioToolbox.framework在“构建阶段”中将AudioToolbox框架添加到目标中。

然后,导入此头文件:

#import <AudioToolbox/AudioServices.h>

3
不需要#import <Cocoa / Cocoa.h>。
猛禽

10
有没有一种方法可以将振动时间减少到不到1秒?
乔治·阿斯达

11
我想补充一点,如果在iOS的“设置”中关闭了振动功能,即使使用这些命令,用户也不会振动。
Denis Kutlubaev

7
在Swift中:(AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))至少从beta 2开始)
Sam Soffes 2014年

1
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); 在iPhone上正确振动,但在iPad上不会发出任何蜂鸣声。
Mangesh 2014年

45

迅捷2.0+

AudioToolbox现在kSystemSoundID_VibrateSystemSoundID类型显示,因此代码为:

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。编译器给你一个错误从尝试投放IntUInt32,但错误读作“无法转换为SystemSoundID”,这是混淆。苹果为什么不让它成为Swift枚举就超出了我。

@aponomarenko的细节,我的答案只是给那些雨燕儿。


这似乎是固定在夫特2 / iOS的9 /的Xcode 7.我用AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)和它编译细
多夫

35

一种简单的方法是使用音频服务:

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

3
#import <AudioToolbox / AudioToolbox.h>,您需要将AudioToolbox.framework添加到项目的构建阶段。
Michael Mangold

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 2015年

4
我写了一个for循环,它的整数从发布的常量开始,然后找出导致振动的原因
Joel Teply 2015年

2
即使在iPhone上启用了静音模式,我也可以确认iPhone在振动。好答案!
vomako

2
截至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


您缺少进口声明
Juan Boero 2015年

导入AudioToolbox.AudioServices
雨果·阿隆索

我自己做的,仅与AVFoundation一起使用。
Juan Boero 2015年

无论如何设置振动持续时间?

您将需要连接多个呼叫,在每个新呼叫之间使用时间间隔
Hugo Alonso

7

对于iPhone 7/7 Plus或更高版本,请使用这三个Haptic反馈API。

可用的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时,需要记住几件事。

注意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

  • 由于生成触觉是一项硬件级的任务,因此在您调用触觉生成代码与实际发生之间可能会有延迟因此,Taptic Engine API都有一种prepare()方法可以使其处于就绪状态。使用“游戏结束”示例:您可能知道游戏即将结束,原因是用户的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

您不想haptic在此方法中创建新实例。您没有在调用impactOccured的同一实例上进行调用prepare
rmaddy19年

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。这种触觉反馈比AudioToolbox API柔和。

对于您的GAME OVER场景,应该使用大量的UI影响反馈。

UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

您可以使用其他触觉反馈样式


1

在Swift中:

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)上,将无能为力
Lal Krishna
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.