如何将iPhone设置为震动一次?
例如,当玩家失去一条生命或游戏结束时,iPhone应该震动。
如何将iPhone设置为震动一次?
例如,当玩家失去一条生命或游戏结束时,iPhone应该震动。
一个简单的方法是使用音频服务:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
摘自“iPhone教程:检查iOS设备功能的更好方法”:
这里有两个看似相似的函数,它们都带有参数kSystemSoundID_Vibrate:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
这两个功能都能使iPhone震动。但是,当你用第一个 功能在不支持振动的设备上,它会发出哔哔声 声音。另一方面,第二个函数不做任何操作 不受支持的设备。所以如果你要振动这个设备 连续地,作为一个警告,常识说,使用函数2。
首先,在构建阶段中将AudioToolbox框架AudioToolbox.framework添加到目标中。
然后,导入这个头文件:
#import <AudioToolbox/AudioServices.h>
在我的旅行中,我发现如果你在录制音频时尝试以下任何一种方法,即使启用了它,设备也不会振动。
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
我的方法在测量设备运动的特定时间被调用。我不得不停止录音,然后在震动发生后重新开始录音。
它是这样的。
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder是一个AVRecorder实例。
希望这能帮助到以前有同样问题的人。
对于以某种方式关闭振动的设备,我遇到了很大的麻烦,但我们无论如何都需要它工作,因为它对我们的应用程序功能至关重要,而且由于它只是文档方法调用的整数,因此它将通过验证。所以我已经尝试了一些在TUNER88/ iossystemsoundlibrary之外的声音
然后我偶然发现了1352,不管静音开关或设备上的设置(设置->震动铃声,震动静音),它都在工作。
- (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);
}
}
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基本上是UInt32的类型别名(花哨的swift typedef),而kSystemSoundID_Vibrate是一个常规Int。编译器给你一个错误,试图从Int转换到UInt32,但错误读为“不能转换为SystemSoundID”,这是令人困惑的。苹果为什么不直接把它做成Swift enum,我真搞不懂。
@aponomarenko详细介绍了,我的答案只是给斯威夫特的。
你可以使用
1) AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);
iPhone和一些新款ipod。
2) AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
ipad。
在我的例子中,我使用的是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];
}
迅速:
import AVFoundation
...
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
重要提示:未来弃用警报。 从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)
or
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
//your callback code when the vibration is done (it may not vibrate in iPod, but this callback will be always called)
}
记得导入AVFoundation
在iOS 10和更新的iphone上,你也可以使用触觉API。这种触觉反馈比AudioToolbox API更柔和。
对于你的GAME OVER场景,一个重UI影响反馈应该是合适的。
UIImpactFeedbackGenerator(风格:.heavy) .impactOccurred ()
你可以使用其他的触觉反馈方式。
对于iPhone 7/7 Plus或更新版本,使用这三个触觉反馈api。
可用的api
通知:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)
可用的样式有。error、。success和。warning。每一种都有自己独特的感觉。 从文档中可以看出:
一个具体的UIFeedbackGenerator子类,创建触觉来传达成功、失败和警告。
对于简单的振动:
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()
可用的样式有。重型、。中型和。轻型。这些都是具有不同“硬度”的简单振动。 从文档中可以看出:
一个具体的UIFeedbackGenerator子类,创建触觉来模拟物理冲击
当用户选择一个项目时使用
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
这是所有触感中最不引人注意的,所以最适合当触感不应该接管应用体验的时候。 从文档中可以看出:
一个具体的UIFeedbackGenerator子类,它创建触觉来指示选择的变化。
笔记
在使用这些api时,有几件事值得记住。
注意一个
你并没有真正创造触觉。你请求系统生成一个触觉图。系统将根据以下决定:
如果触觉在设备上是可能的(在这种情况下是否有Taptic引擎) 应用程序是否可以记录音频(录制过程中不会产生触觉,以防止不必要的干扰) 是否在系统设置中启用触觉。
因此,如果不可能,系统将无声地忽略您的触觉请求。如果这是由于不支持的设备,您可以尝试这样做:
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
Due to the fact that generating haptics is a hardware-level task, there may be latency between when you call the haptic-generation code, and when it actually happens. For this reason, the Taptic Engine APIs all have a prepare() method, to put it in a state of readiness. Using your Game Over example: You may know that the game is about to end, by the user having very low HP, or a dangerous monster being near them. If you don't generate a haptic within a few seconds, the Taptic Engine will go back into an idle state (to save battery life)
在这种情况下,准备Taptic引擎将创建更高质量、更灵敏的体验。
例如,假设你的应用程序使用平移手势识别器来改变世界可见的部分。当用户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
}