Câu trả lời:
Từ " Hướng dẫn iPhone: Cách tốt hơn để kiểm tra khả năng của thiết bị iOS ":
Có hai hàm dường như giống nhau có tham số kSystemSoundID_Vibrate
:
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Cả hai chức năng đều làm rung iPhone. Nhưng, khi bạn sử dụng chức năng đầu tiên trên các thiết bị không hỗ trợ rung, nó sẽ phát ra tiếng bíp. Mặt khác, chức năng thứ hai không làm gì trên các thiết bị không được hỗ trợ. Vì vậy, nếu bạn định rung thiết bị liên tục, như một cảnh báo, lẽ thường, hãy sử dụng chức năng 2.
Đầu tiên, thêm khung AudioToolbox AudioToolbox.framework
vào mục tiêu của bạn trong Build Phase.
Sau đó, nhập tệp tiêu đề này:
#import <AudioToolbox/AudioServices.h>
AudioServicesPlayAlertSound(UInt32(kSystemSoundID_Vibrate))
(ít nhất là từ phiên bản beta 2)
AudioToolbox hiện trình bày kSystemSoundID_Vibrate
dưới dạng một SystemSoundID
loại, vì vậy mã là:
import AudioToolbox.AudioServices
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
Thay vì phải đi qua bước diễn viên phụ
(Đạo cụ cho @Dov)
Và, đây là cách bạn làm điều đó trên Swift (trong trường hợp bạn gặp rắc rối giống như tôi đã làm)
Liên kết với AudioToolbox.framework
(Chuyển đến dự án của bạn, chọn mục tiêu của bạn, xây dựng các giai đoạn, Liên kết nhị phân với Thư viện, thêm thư viện ở đó)
Khi đã hoàn thành:
import AudioToolbox.AudioServices
// Use either of these
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
Điều SystemSoundID
cơ bản là về cơ bản là một typealias
(swift ưa thích typedef
) cho a UInt32
, và kSystemSoundID_Vibrate
là một thường xuyên Int
. Trình biên dịch cung cấp cho bạn một lỗi khi cố gắng truyền từ Int
sang UInt32
, nhưng lỗi này là "Không thể chuyển đổi thành SystemSoundID", điều này gây nhầm lẫn. Tại sao táo không biến nó thành một enum Swift vượt xa tôi.
@ aponomarenko đi vào chi tiết, câu trả lời của tôi chỉ dành cho Swifters ngoài kia.
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
và nó được biên dịch tốt
Một cách đơn giản để làm như vậy là với Dịch vụ âm thanh:
#import <AudioToolbox/AudioToolbox.h>
...
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Tôi đã gặp rắc rối lớn với điều này đối với các thiết bị đã tắt rung theo một cách nào đó, nhưng chúng tôi cần nó hoạt động bất kể vì nó rất quan trọng đối với chức năng ứng dụng của chúng tôi và vì nó chỉ là số nguyên cho một cuộc gọi phương thức được ghi lại, nên nó sẽ vượt qua Thẩm định. Vì vậy, tôi đã thử một số âm thanh nằm ngoài những âm thanh được ghi chép tốt ở đây: TUNER88 / iOSSystemSoundL Library
Sau đó, tôi đã vấp ngã vào năm 1352, đang hoạt động bất kể công tắc im lặng hoặc cài đặt trên thiết bị (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);
}
}
Lưu ý quan trọng: Thông báo về sự phản đối trong tương lai.
Kể từ iOS 9.0 , mô tả chức năng API cho:
AudioServicesPlaySystemSound(inSystemSoundID: SystemSoundID)
AudioServicesPlayAlertSound(inSystemSoundID: SystemSoundID)
bao gồm các lưu ý sau:
This function will be deprecated in a future release.
Use AudioServicesPlayAlertSoundWithCompletion or
AudioServicesPlaySystemSoundWithCompletion instead.
Cách đi đúng sẽ sử dụng bất kỳ một trong hai điều sau:
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil)
hoặc là
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
//your callback code when the vibration is done (it may not vibrate in iPod, but this callback will be always called)
}
nhớ
import AVFoundation
Đối với iPhone 7/7 Plus hoặc mới hơn, hãy sử dụng ba API phản hồi Haptic này.
let generator = UINotificationFeedbackGenerator()
generator.notificationOccured(style: .error)
Kiểu dáng có thể là .error
, .success
, và .warning
. Mỗi người có một cảm nhận riêng biệt.
Từ các tài liệu :
Một
UIFeedbackGenerator
lớp con cụ thể tạo ra haptics để truyền đạt những thành công, thất bại và cảnh báo.
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccured()
Kiểu dáng có thể là .heavy
, .medium
, và .light
. Đây là những rung động đơn giản với mức độ "cứng" khác nhau.
Từ các tài liệu :
Một
UIFeedbackGenerator
lớp con cụ thể tạo ra haptics để mô phỏng các tác động vật lý
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
Đây là điều ít được chú ý nhất trong tất cả các haptics, và do đó, phù hợp nhất cho khi haptics không nên chiếm lĩnh trải nghiệm ứng dụng.
Từ các tài liệu :
Một
UIFeedbackGenerator
lớp con cụ thể tạo ra haptics để chỉ ra sự thay đổi trong lựa chọn.
Có một vài điều đáng ghi nhớ khi sử dụng các API này.
Bạn không thực sự tạo ra haptic. Bạn yêu cầu hệ thống tạo ra một haptic. Hệ thống sẽ quyết định dựa trên những điều dưới đây:
Do đó, hệ thống sẽ âm thầm bỏ qua yêu cầu của bạn cho một haptic nếu không thể. Nếu đây là do một thiết bị không được hỗ trợ, bạn có thể thử điều này:
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
}
Thay thế các nhận xét trong switch
- các case
tuyên bố và mã thế hệ haptic này sẽ được chuyển sang các thiết bị iOS khác. Nó sẽ tạo ra mức độ haptic cao nhất có thể.
prepare()
phương pháp, để đưa nó vào trạng thái sẵn sàng. Sử dụng ví dụ về trò chơi của bạn: Bạn có thể biết rằng trò chơi sắp kết thúc, bởi người dùng có lượng HP rất thấp hoặc một con quái vật nguy hiểm đang ở gần họ.
Trong trường hợp này, việc chuẩn bị Taptic Engine sẽ tạo ra trải nghiệm chất lượng cao hơn, phản ứng nhanh hơn.
Ví dụ: giả sử ứng dụng của bạn sử dụng trình nhận dạng cử chỉ pan để thay đổi phần hiển thị của thế giới. Bạn muốn có một haptic để tạo khi người dùng 'trông' tròn 360 độ. Đây là cách bạn có thể sử dụng 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
bên trong phương thức này. Bạn không gọi impactOccured
trong cùng một ví dụ mà bạn gọi prepare
.
Trong các chuyến đi của mình, tôi đã thấy rằng nếu bạn thử một trong những điều sau đây trong khi bạn đang ghi âm thanh, thiết bị sẽ không rung ngay cả khi được bật.
1) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
2) AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Phương pháp của tôi được gọi vào một thời điểm cụ thể trong việc đo các chuyển động của thiết bị. Tôi đã phải dừng ghi âm và sau đó khởi động lại sau khi rung động xảy ra.
Nó trông như thế này.
-(void)vibrate {
[recorder stop];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[recorder start];
}
recorder
là một ví dụ AVRecorder.
Hy vọng điều này sẽ giúp những người khác đã có cùng một vấn đề trước đây.
Trong iOS 10 và trên các iPhone mới hơn, bạn cũng có thể sử dụng API haptic. Phản hồi xúc giác này mềm hơn API AudioToolbox.
Đối với kịch bản GAME OVER của bạn, phản hồi tác động UI nặng sẽ phù hợp.
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
Bạn có thể sử dụng các kiểu phản hồi xúc giác khác .
Trong trường hợp của tôi, tôi đã sử dụng AVCaptureSession. AudioToolbox đang trong giai đoạn xây dựng của dự án và nó đã được nhập nhưng vẫn không hoạt động. Để làm cho nó hoạt động, tôi dừng phiên trước khi rung và tiếp tục sau đó.
#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];
}
Bạn có thể dùng
1) Dịch vụ âm thanhPlayAlertSound (kSystemSoundID_Vibrate);
cho iPhone và một vài iPod mới hơn.
2) Dịch vụ âm thanhPlaySystemSound (kSystemSoundID_Vibrate);
cho iPad.