如何设置 iPhone 为单次震动?
例如,当玩家失去一条生命或游戏结束时,iPhone 应该进行震动。
如何设置 iPhone 为单次震动?
例如,当玩家失去一条生命或游戏结束时,iPhone 应该进行震动。
有两个看似相似的函数都带有参数kSystemSoundID_Vibrate
:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
这两个函数都可以让iPhone震动。但是,如果你在不支持振动的设备上使用第一个函数,它会播放一声蜂鸣声。另一方面,第二个函数在不支持振动的设备上不起作用。因此,如果要将设备连续震动作为警报,常识告诉我们应该使用第二个函数。
首先,在Build Phases中将AudioToolbox框架AudioToolbox.framework
添加到你的目标项目中。
然后,导入这个头文件:
#import <AudioToolbox/AudioServices.h>
AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))
(至少在 beta 2 版本中)。 - Sam SoffesAudioToolbox现在将kSystemSoundID_Vibrate
呈现为SystemSoundID
类型,因此代码如下:
import AudioToolbox.AudioServices
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
无需进行额外的强制类型转换
(感谢@Dov)
而且,这是在Swift上执行的方法(如果您遇到了与我一样的麻烦)
链接AudioToolbox.framework
(进入您的项目,选择目标,构建阶段,链接二进制文件与库,将库添加到其中)
完成后:
import AudioToolbox.AudioServices
// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
奇怪的是,SystemSoundID
本质上是一个typealias
(高级Swift中的typedef
),代表一个UInt32
,而kSystemSoundID_Vibrate
则是一个普通的Int
。试图将Int
转换为UInt32
时,编译器会报错,但错误信息却显示“无法转换为SystemSoundID”,这很令人困惑。苹果为什么不直接将其制作成Swift枚举我就不明白了。
@aponomarenko提供了更详细的解释,我的回答只是针对那些熟悉Swift的人。
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
,并且编译通过了。 - Dov一个简单的方法是使用音频服务:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
- (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);
}
}
重要提示:未来版本可能会弃用。
从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
对于 iPhone 7/7 Plus 或更新型号,使用这三个触觉反馈 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时,有几件事值得记住。
实际上你并没有创建触觉反馈。你只是向系统请求生成触觉反馈。系统将基于以下内容进行决策:
因此,如果不可能生成触觉反馈,系统将默默忽略您的请求。如果这是由于不支持的设备造成的,您可以尝试以下方法:
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
}
< p >替换switch
-case
语句中的注释,此触觉生成代码将可移植到其他iOS设备。它将生成最高级别的触觉反馈。
prepare()
方法的原因,以使其处于准备状态。使用 Game Over 示例:您可以通过用户的生命值非常低或危险怪物接近他们来知道游戏即将结束。
在这种情况下,准备 Taptic 引擎将创建更高质量,更具响应性的体验。
例如,假设您的应用程序使用平移手势识别器来更改可见的世界部分。当用户“环顾四周”时,您希望生成触觉反馈。以下是如何使用 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
! - Benjhaptic
实例。你没有在同一个实例上调用 impactOccured
和 prepare
。 - rmaddy1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
我在设备运动测量的特定时间调用了我的方法。我必须停止记录,然后在振动发生后重新启动记录。
效果如下所示。
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder
是一个 AVRecorder 实例。
希望这可以帮助其他之前遇到过同样问题的人。
如果你正在使用Xamarin (monotouch)框架,只需要调用以下代码
SystemSound.Vibrate.PlayAlertSound()
#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];
}