ios 让 iPhone 振动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4724980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making the iPhone vibrate
提问by system
How can the iPhone be set to vibrate once?
iPhone如何设置震动一次?
For example, when a player loses a life or the game is over, the iPhone should vibrate.
例如,当玩家失去生命或游戏结束时,iPhone 应该会振动。
回答by linuxbuild
From "iPhone Tutorial: Better way to check capabilities of iOS devices":
来自“ iPhone 教程:检查 iOS 设备功能的更好方法”:
There are two seemingly similar functions that take a parameter kSystemSoundID_Vibrate
:
有两个看似相似的函数接受一个参数kSystemSoundID_Vibrate
:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Both of the functions vibrate the iPhone. But, when you use the first function on devices that don't support vibration, it plays a beep sound. The second function, on the other hand, does nothing on unsupported devices. So if you are going to vibrate the device continuously, as an alert, common sense says, use function 2.
这两个功能都会使 iPhone 振动。但是,当您在不支持振动的设备上使用第一个功能时,它会发出哔声。另一方面,第二个函数在不受支持的设备上不执行任何操作。因此,如果您要连续振动设备,正如常识所说的那样,请使用功能 2。
First, add the AudioToolbox framework AudioToolbox.framework
to your target in Build Phases.
首先,AudioToolbox.framework
在 Build Phases中将 AudioToolbox 框架添加到您的目标。
Then, import this header file:
然后,导入这个头文件:
#import <AudioToolbox/AudioServices.h>
回答by Can
Swift 2.0+
斯威夫特 2.0+
AudioToolbox now presents the kSystemSoundID_Vibrate
as a SystemSoundID
type, so the code is:
AudioToolbox 现在将 呈现kSystemSoundID_Vibrate
为一种SystemSoundID
类型,因此代码为:
import AudioToolbox.AudioServices
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
Instead of having to go thru the extra cast step
而不是必须通过额外的演员步骤
(Props to @Dov)
(给@Dov 的道具)
Original Answer (Swift 1.x)
原始答案 (Swift 1.x)
And, here's how you do it on Swift(in case you ran into the same trouble as I did)
而且,这是你在Swift上的做法(以防你遇到和我一样的麻烦)
Link against AudioToolbox.framework
(Go to your project, select your target, build phases, Link Binary with Libraries, add the library there)
链接AudioToolbox.framework
(转到您的项目,选择您的目标,构建阶段,将二进制文件与库链接,在那里添加库)
Once that is completed:
一旦完成:
import AudioToolbox.AudioServices
// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
The cheesy thing is that SystemSoundID
is basically a typealias
(fancy swift typedef
) for a UInt32
, and the kSystemSoundID_Vibrate
is a regular Int
. The compiler gives you an error for trying to cast from Int
to UInt32
, but the error reads as "Cannot convert to SystemSoundID", which is confusing. Why didn't apple just make it a Swift enum is beyond me.
俗气的是,SystemSoundID
它基本上是 a 的typealias
(花哨的 swift typedef
)UInt32
,而 thekSystemSoundID_Vibrate
是常规的Int
. 编译器会提示您尝试从Int
to 进行转换UInt32
,但该错误显示为“无法转换为 SystemSoundID”,这令人困惑。为什么苹果不让它成为一个 Swift 枚举超出我的范围。
@aponomarenko's goes into the details, my answer is just for the Swifters out there.
@aponomarenko 会详细介绍,我的答案仅适用于那里的 Swifters。
回答by fsaint
A simple way to do so is with Audio Services:
一个简单的方法是使用音频服务:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
回答by Joel Teply
I had great trouble with this for devices that had vibration turned off in some manner, but we needed it to work regardless, because it is critical to our application functioning, and since it is just an integer to a documented method call, it will pass validation. So I have tried some sounds that were outside of the well documented ones here: TUNER88/iOSSystemSoundsLibrary
对于以某种方式关闭振动的设备,我遇到了很大的麻烦,但无论如何我们都需要它工作,因为它对我们的应用程序运行至关重要,而且由于它只是记录方法调用的整数,它将通过验证。所以我尝试了一些这里有据可查的声音之外的声音:TUNER88/iOSSystemSoundsLibrary
I have then stumbled upon 1352, which is working regardless of the silent switch or the settings on the device (Settings->vibrate on ring, vibrate on silent)
.
然后我已经在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);
}
}
回答by Hugo Alonso
Important Note: Alert of Future Deprecation.
As of iOS 9.0, the APIfunctions description for:
重要提示:未来弃用警报。
从iOS 9.0 开始,API函数描述为:
AudioServicesPlaySystemSound(inSystemSoundID: SystemSoundID)
AudioServicesPlayAlertSound(inSystemSoundID: SystemSoundID)
includes the following note:
包括以下说明:
This function will be deprecated in a future release.
Use AudioServicesPlayAlertSoundWithCompletion or
AudioServicesPlaySystemSoundWithCompletion instead.
The right way to go will be using any of these two:
正确的方法是使用这两个中的任何一个:
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)
}
remember to
import AVFoundation
记得
import AVFoundation
回答by Benj
For an iPhone 7/7 Plus or newer, use these three Haptic feedback APIs.
对于 iPhone 7/7 Plus 或更新机型,请使用这三个 Haptic 反馈 API。
Available APIs
可用的 API
For notifications:
对于通知:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)
Available styles are .error
, .success
, and .warning
. Each has its own distinctive feel.
From the docs:
可用的样式.error
,.success
和.warning
。每个人都有自己独特的感觉。
从文档:
A concrete
UIFeedbackGenerator
subclass that creates haptics to communicate successes, failures, and warnings.
UIFeedbackGenerator
创建触觉以传达成功、失败和警告的具体子类。
For simple vibrations:
对于简单的振动:
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()
Available styles are .heavy
, .medium
, and .light
. These are simple vibrations with varying degrees of "hardness".
From the docs:
可用的样式.heavy
,.medium
和.light
。这些是具有不同程度“硬度”的简单振动。
从文档:
A concrete
UIFeedbackGenerator
subclass that creates haptics to simulate physical impacts
UIFeedbackGenerator
创建触觉以模拟物理影响的具体子类
For when the user selected an item
当用户选择一个项目时
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
This is the least noticeable of all the haptics, and so is the most suitable for when haptics should not be taking over the app experience.
From the docs:
这是所有触觉中最不引人注目的,因此最适合触觉不应该接管应用程序体验的情况。
从文档:
A concrete
UIFeedbackGenerator
subclass that creates haptics to indicate a change in selection.
UIFeedbackGenerator
创建触觉以指示选择更改的具体子类。
Notes
笔记
There are a couple of things worth remembering when using these APIs.
在使用这些 API 时,有几件事值得记住。
Note A
注释 A
You do not actually create the haptic.You request the systemgenerate a haptic. The system will decide based on the below:
您实际上并没有创建触觉。您请求系统生成触觉。系统将根据以下情况作出决定:
- If haptics are possible on the device (whether it has a Taptic Engine in this case)
- Whether the app may record audio (haptics do not generate during recording to prevent unwanted interference)
- Whether haptics are enabled in system Settings.
- 如果设备上可以使用触觉(在这种情况下它是否具有 Taptic Engine)
- 应用程序是否可以录制音频(录制过程中不会产生触觉以防止不必要的干扰)
- 是否在系统设置中启用触觉。
Therefore, the system will silently ignore your request for a haptic if it is not possible. If this is due to an unsupported device, you could try this:
因此,如果不可能,系统将默默地忽略您对触觉的请求。如果这是由于不受支持的设备造成的,您可以尝试以下操作:
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
}
Substitute the comments in the switch
-case
statements, and this haptic generation code will be portable to other iOS devices. It will generate the highest level of haptic possible.
替换switch
-case
语句中的注释,此触觉生成代码将可移植到其他 iOS 设备。它将产生尽可能高的触觉。
Note B
备注 B
- Due to the fact that generating haptics is a hardware-level task, there may be latency between when you callthe 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 Engine API 都有一个
prepare()
方法,可以将其置于就绪状态。使用您的游戏结束示例:您可能知道游戏即将结束,因为用户 HP 非常低,或者附近有危险的怪物。 - 如果您在几秒钟内没有产生触觉,触觉引擎将返回空闲状态(以节省电池寿命)
In this case, preparing the Taptic Engine would create a higher-quality, more responsive experience.
在这种情况下,准备 Taptic Engine 将创造更高质量、更灵敏的体验。
For example, let's say your app uses a pan gesture recogniser to change the portion of the world visible. You want a haptic to generate when the user 'looks' round 360 degrees. Here is how you could use prepare()
:
例如,假设您的应用程序使用平移手势识别器来更改可见世界的部分。您希望在用户 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
}
回答by Wheelie
And if you're using Xamarin (monotouch) framework, simply call
如果您使用的是 Xamarin (monotouch) 框架,只需调用
SystemSound.Vibrate.PlayAlertSound()
回答by Sebastien Peek
In my travels I have found that if you try either of the following while you are recording audio, the device will not vibrate even if it is enabled.
在我的旅行中,我发现如果您在录制音频时尝试以下任一方法,即使启用了设备也不会振动。
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
My method was called at a specific time in the measurement of the devices movements. I had to stop the recording and then restart it after the vibration had occurred.
我的方法在测量设备运动的特定时间被调用。我不得不停止录音,然后在振动发生后重新启动。
It looked like this.
它看起来像这样。
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder
is an AVRecorder instance.
recorder
是一个 AVRecorder 实例。
Hope this helps others that have had the same problem before.
希望这可以帮助之前遇到相同问题的其他人。
回答by samwize
In iOS 10, and on newer iPhones, you can also use haptic API. This haptic feedback is softer than the AudioToolbox API.
在 iOS 10 和较新的 iPhone 上,您还可以使用触觉 API。这种触觉反馈比 AudioToolbox API 更柔和。
For your GAME OVER scenario, a heavy UI impact feedback should be suitable.
对于您的 GAME OVER 场景,重 UI 影响反馈应该是合适的。
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
You could use the other haptic feedback styles.
您可以使用其他触觉反馈样式。
回答by Eric
In Swift:
在斯威夫特:
import AVFoundation
...
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))