【问题标题】:Making the iPhone vibrate让 iPhone 振动
【发布时间】:2011-06-11 03:10:06
【问题描述】:

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

例如,当玩家失去生命或游戏结束时,iPhone 应该会振动。

【问题讨论】:

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

标签: ios cocoa-touch avfoundation vibration


【解决方案1】:

来自“iPhone Tutorial: Better way to check capabilities of iOS devices”:

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

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

这两个功能都会震动 iPhone。但是,当您使用第一个 在不支持振动的设备上运行,它会发出哔声 声音。另一方面,第二个函数对 不支持的设备。因此,如果您要振动设备 正如常识所说,不断地使用函数 2。

首先,在 Build Phases 中将 AudioToolbox 框架 AudioToolbox.framework 添加到您的目标中。

然后,导入这个头文件:

#import <AudioToolbox/AudioServices.h>

【讨论】:

  • #import 不是必需的。
  • 有没有办法把振动时间减少到1秒以内?
  • 我想补充一点,如果在iOS的设置中关闭振动,即使你使用这些命令用户也不会得到振动。
  • 在 Swift 中:AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))(至少从 beta 2 开始)
  • AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);在 iPhone 上可以正常振动,但在 iPad 上不会发出任何哔声。
【解决方案2】:

斯威夫特 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 基本上是UInt32typealias(花式swift typedef),而kSystemSoundID_Vibrate 是常规Int。编译器会提示您尝试从 Int 转换为 UInt32 时出现错误,但错误显示为“无法转换为 SystemSoundID”,这令人困惑。为什么苹果不把它变成一个 Swift 枚举超出了我的范围。

@aponomarenko 的详细信息,我的回答只是针对那里的 Swifters。

【讨论】:

  • 这似乎在 Swift 2/iOS 9/Xcode 7 中得到修复。我使用了AudioServicesPlaySystemSound(kSystemSoundID_Vibrate),它编译得很好
【解决方案3】:

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

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

【讨论】:

  • #import 您需要将 AudioToolbox.framework 添加到项目的构建阶段。
【解决方案4】:

对于以某种方式关闭振动的设备,我遇到了很大的麻烦,但无论如何我们都需要它工作,因为它对我们的应用程序运行至关重要,而且它只是记录方法调用的整数,它将通过验证。所以我在这里尝试了一些有据可查的声音:TUNER88/iOSSystemSoundsLibrary

然后我偶然发现了 1352,无论静音开关或设备 (Settings-&gt;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);
     }
}

【讨论】:

  • 使用命名别名而不是魔术常量总是更好,例如 kSystemSoundID_Vibrate 而不是 1352。我鼓励您更新您的答案。
  • 我同意使用这个魔法 1352 并不理想,但即使设备上的振动开关关闭,我也找不到任何其他方式来强制振动。这似乎是唯一的方法。
  • 我写了一个 for 循环,其中的整数从已发布的常量开始,并找出了是哪一个引起了振动
  • 我可以确认即使在 iPhone 上激活了静音模式,iPhone 也会振动。很好的答案!
  • AudioServicesPlaySystemSound (1352) 在 2016 年 1 月时仍适用于 iPhone,无论静音开关位置如何
【解决方案5】:

重要提示:未来弃用警告。

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 一个。
  • 无论如何设置振动持续时间?
  • 您将需要连接多个呼叫,在每个新呼叫之间使用时间间隔
【解决方案6】:

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

可用的 API

对于通知:

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

可用样式为.error.success.warning。每个人都有自己独特的感觉。
来自docs

一个具体的UIFeedbackGenerator 子类,它创建触觉来传达成功、失败和警告。

对于简单的振动:

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

可用样式为.heavy.medium.light。这些是具有不同“硬度”程度的简单振动。
来自docs

一个具体的UIFeedbackGenerator 子类,它创建触觉以模拟物理影响

当用户选择一个项目时

let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()

这是所有触感中最不引人注目的,因此最适合触感不应该接管应用体验的情况。
来自docs

一个具体的UIFeedbackGenerator 子类,它创建触觉以指示选择的变化。

注意事项

在使用这些 API 时有几件事值得记住。

注A

您实际上并未创建触觉。请求系统生成触觉。系统将根据以下情况做出决定:

  • 如果设备上支持触觉(在这种情况下是否有触觉引擎)
  • 应用是否可以录制音频(录制过程中不会产生触觉以防止不必要的干扰)
  • 是否在系统设置中启用了触觉。

因此,如果不可能,系统将默默地忽略您对触觉的请求。如果这是由于设备不受支持,您可以尝试以下操作:

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 语句中的 cmets,此触觉生成代码将可移植到其他 iOS 设备。它将产生最高级别的触觉。

注B

  • 由于生成触觉是一个硬件级别的任务,在您调用触觉生成代码和它确实发生了。 出于这个原因,Taptic Engine API 都有一个prepare() 方法,以使其处于就绪状态。使用您的 Game Over 示例:您可能知道游戏即将结束,因为用户的 HP 非常低,或者附近有危险的怪物。
  • 如果您在几秒钟内未生成触觉,触觉引擎将回到空闲状态(以节省电池寿命)


在这种情况下,准备 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 的新实例。您没有在调用 prepare 的同一实例上调用 impactOccured
  • 你好 @Benj 我想通过录音实现振动,但在录音时触觉不起作用。
  • @DikenShah 如前所述,我相信我在某处读到这是为了尽量减少麦克风干扰而有意采取的举措。由于麦克风检测到振动,并且 Taptic Engine 产生振动,这显然是个问题。
  • @Div 我找到了解决方案。感谢您的回答
【解决方案7】:

如果您使用的是 Xamarin (monotouch) 框架,只需调用

SystemSound.Vibrate.PlayAlertSound()

【讨论】:

    【解决方案8】:

    在我的旅行中,我发现如果您在录制音频时尝试以下任一操作,即使启用了设备也不会振动。

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

    我的方法是在测量设备运动的特定时间调用的。我不得不停止录制,然后在振动发生后重新开始。

    看起来像这样。

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

    recorder 是一个 AVRecorder 实例。

    希望这对以前遇到过同样问题的其他人有所帮助。

    【讨论】:

      【解决方案9】:

      在 iOS 10 和较新的 iPhone 上,您还可以使用触觉 API。这种触觉反馈比 AudioToolbox API 更柔和。

      对于您的 GAME OVER 场景,应该适合使用重度 UI 影响反馈。

      UIImpactFeedbackGenerator(style: .heavy).impactOccurred()

      您可以使用other haptic feedback styles

      【讨论】:

        【解决方案10】:

        在斯威夫特中:

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

        【讨论】:

          【解决方案11】:

          就我而言,我使用的是 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];
          }
          

          【讨论】:

            【解决方案12】:

            你可以使用

            1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);

            适用于 iPhone 和一些较新的 iPod。

            2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

            适用于 iPad。

            【讨论】:

            • iPod touch 和 iPad 无法振动。
            • 在没有振动功能的设备(如 iPod Touch)上,这将无济于事
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-09-20
            • 2023-03-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多