Swift 中的循环振动
Loop vibration in Swift
我正在使用 AVPlayer 播放声音。我试图让 iPhone 在此声音期间振动。
我可以通过以下方式产生振动:
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
但如果我使用:尝试循环振动时遇到问题:
vibrationTimer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(ViewController.loopVibration), userInfo: nil, repeats: true)
@objc func loopVibration() {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
函数 loopVibration() 每两秒调用一次,但它不振动。
不允许使用持续振动,您的应用可能会被拒绝。如果你仍然想这样做,你可以尝试这样的事情:
func vibrate() {
for i in 0...13 {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(Double(i) * 0.1 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
self.vibrate()
})
}
}
不确定为什么这对您不起作用——以下示例适用于我的测试设备(iPhone X,iOS 11.2)。
下面的 ViewController 示例包括用于播放单一声音、播放单一振动、循环声音和循环振动的出口。 "Chirp"声音是一个1s的wav文件。
请注意,由于这是一个示例,下面的代码不会处理系统声音,如果 ViewController 被隐藏,也不会使计时器无效。如果您对此进行调整,请确保适当地管理您的系统资源。
//
// ViewController.swift
//
import UIKit
import AudioToolbox
class ViewController: UIViewController {
static let soundId: SystemSoundID? = {
guard let soundURL = Bundle.main.url(forResource: "Chirp", withExtension: "wav") else {
return nil
}
var soundId: SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundURL as CFURL, &soundId)
return soundId
}()
static let timerInterval: TimeInterval = 2
var soundTimer: Timer?
var vibrationTimer: Timer?
var playCount = 0 {
didSet {
playCountLabel.text = String(playCount)
}
}
func invalidateTimers() {
if let vibrationTimer = vibrationTimer {
vibrationTimer.invalidate()
}
if let soundTimer = soundTimer {
soundTimer.invalidate()
}
}
@IBOutlet weak var playCountLabel: UILabel!
@IBAction func playSound(_ sender: Any) {
if let soundId = ViewController.soundId {
AudioServicesPlaySystemSound(soundId)
playCount += 1
}
}
@IBAction func loopSound(_ sender: Any) {
invalidateTimers()
soundTimer = Timer.scheduledTimer(timeInterval: ViewController.timerInterval, target: self, selector: #selector(playSound(_:)), userInfo: nil, repeats: true)
}
@IBAction func vibrate(_ sender: Any) {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
playCount += 1
}
@IBAction func loopVibrate(_ sender: Any) {
invalidateTimers()
soundTimer = Timer.scheduledTimer(timeInterval: ViewController.timerInterval, target: self, selector: #selector(vibrate(_:)), userInfo: nil, repeats: true)
}
@IBAction func cancelAll(_ sender: Any) {
invalidateTimers()
}
}
我正在使用 AVPlayer 播放声音。我试图让 iPhone 在此声音期间振动。
我可以通过以下方式产生振动:
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
但如果我使用:尝试循环振动时遇到问题:
vibrationTimer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(ViewController.loopVibration), userInfo: nil, repeats: true)
@objc func loopVibration() {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
函数 loopVibration() 每两秒调用一次,但它不振动。
不允许使用持续振动,您的应用可能会被拒绝。如果你仍然想这样做,你可以尝试这样的事情:
func vibrate() {
for i in 0...13 {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(Double(i) * 0.1 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
self.vibrate()
})
}
}
不确定为什么这对您不起作用——以下示例适用于我的测试设备(iPhone X,iOS 11.2)。
下面的 ViewController 示例包括用于播放单一声音、播放单一振动、循环声音和循环振动的出口。 "Chirp"声音是一个1s的wav文件。
请注意,由于这是一个示例,下面的代码不会处理系统声音,如果 ViewController 被隐藏,也不会使计时器无效。如果您对此进行调整,请确保适当地管理您的系统资源。
//
// ViewController.swift
//
import UIKit
import AudioToolbox
class ViewController: UIViewController {
static let soundId: SystemSoundID? = {
guard let soundURL = Bundle.main.url(forResource: "Chirp", withExtension: "wav") else {
return nil
}
var soundId: SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundURL as CFURL, &soundId)
return soundId
}()
static let timerInterval: TimeInterval = 2
var soundTimer: Timer?
var vibrationTimer: Timer?
var playCount = 0 {
didSet {
playCountLabel.text = String(playCount)
}
}
func invalidateTimers() {
if let vibrationTimer = vibrationTimer {
vibrationTimer.invalidate()
}
if let soundTimer = soundTimer {
soundTimer.invalidate()
}
}
@IBOutlet weak var playCountLabel: UILabel!
@IBAction func playSound(_ sender: Any) {
if let soundId = ViewController.soundId {
AudioServicesPlaySystemSound(soundId)
playCount += 1
}
}
@IBAction func loopSound(_ sender: Any) {
invalidateTimers()
soundTimer = Timer.scheduledTimer(timeInterval: ViewController.timerInterval, target: self, selector: #selector(playSound(_:)), userInfo: nil, repeats: true)
}
@IBAction func vibrate(_ sender: Any) {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
playCount += 1
}
@IBAction func loopVibrate(_ sender: Any) {
invalidateTimers()
soundTimer = Timer.scheduledTimer(timeInterval: ViewController.timerInterval, target: self, selector: #selector(vibrate(_:)), userInfo: nil, repeats: true)
}
@IBAction func cancelAll(_ sender: Any) {
invalidateTimers()
}
}