Answers:
从“ iPhone教程:检查iOS设备功能的更好方法 ”开始:
有两个看似相似的函数带有一个参数kSystemSoundID_Vibrate
:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
这两个功能都使iPhone震动。但是,当您在不支持振动的设备上使用第一个功能时,它会发出蜂鸣声。另一方面,第二个功能在不受支持的设备上不执行任何操作。因此,如果您要连续振动设备,如常识所说,作为警报,请使用功能2。
首先,AudioToolbox.framework
在“构建阶段”中将AudioToolbox框架添加到目标中。
然后,导入此头文件:
#import <AudioToolbox/AudioServices.h>
AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))
至少从beta 2开始)
AudioToolbox现在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
(花式迅速typedef
)了UInt32
,而且kSystemSoundID_Vibrate
是有规律的Int
。编译器给你一个错误从尝试投放Int
到UInt32
,但错误读作“无法转换为SystemSoundID”,这是混淆。苹果为什么不让它成为Swift枚举就超出了我。
@aponomarenko的细节,我的答案只是给那些雨燕儿。
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
和它编译细
一种简单的方法是使用音频服务:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
对于以某种方式关闭了振动的设备,我在这方面遇到了很大的麻烦,但是我们无论如何都需要使其工作,因为这对于我们的应用程序功能至关重要,并且由于它只是记录的方法调用的整数,因此它将通过验证。因此,我尝试了一些声音,这些声音不在此处有据可查的范围内: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);
}
}
重要说明:即将弃用的警报。
从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或更高版本,请使用这三个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时,需要记住几件事。
您实际上并没有创建触觉。您请求系统生成触觉。系统将基于以下决定:
因此,如果不可能,系统将静默忽略您对触觉的请求。如果这是由于设备不受支持所致,则可以尝试以下操作:
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设备。它将产生最高水平的触觉。
prepare()
方法可以使其处于就绪状态。使用“游戏结束”示例:您可能知道游戏即将结束,原因是用户的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
在此方法中创建新实例。您没有在调用impactOccured
的同一实例上进行调用prepare
。
在旅行中,我发现,如果您在录制音频时尝试以下任何一种方法,则即使启用该设备也不会振动。
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
在测量设备运动的特定时间调用了我的方法。我必须停止录制,然后在发生振动后重新开始录制。
看起来像这样。
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder
是AVRecorder实例。
希望这可以帮助以前遇到过相同问题的其他人。
就我而言,我正在使用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];
}
您可以使用
1)AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
适用于iPhone和较新的iPod。
2)AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
适用于iPad。