😬
[iOS]ButtonをTapしたときに効果音を再生し、連続Tapにも対応する
概要
AVAudioPlayer
のplay()
methodを呼ぶことで、Buttonをタップしたときに効果音を流す機能を実装できる。
素直にplay()
を呼ぶだけでは、連続でタップしたときに、直前のタップによる効果音が再生中なら、新たにタップしたときの効果音は再生されない。
play()
を呼ぶ前に、再生時間を0
にセットすることで、連続したタップでも、毎回、効果音を再生できる。
背景
Buttonをタップしたときに、効果音を再生したいという要望がある。
AVAudioPlayer
を使用することで、以下のように実装できる。
class ViewController: UIViewController {
let audioPlayer: AVAudioPlayer? = {
// Assetsに登録した音源の読み込み
let data = NSDataAsset(name: "SampleSound")
// 音源の登録
let player = try? AVAudioPlayer(data: data!.data)
player?.prepareToPlay()
return player
}()
let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
// Buttonの見た目とGestureの登録
private func setupView() {
view.addSubview(button)
button.frame = CGRect(x: 100, y: 100, width: 200, height: 100)
button.backgroundColor = .blue
button.setTitle("tap Here", for: .normal)
button.addTarget(nil, action: #selector(didTap), for: .touchUpInside)
}
// Buttonがタップされた時に呼ばれる
@objc func didTap() {
// 音源を再生する
audioPlayer?.play()
}
}
問題
上記の実装では、再生中の効果音が鳴り終わる前に連続してタップしたときに、一度しか効果音が再生されない。
(e.g. 1秒で3回タップしても、最初の一度しか効果音が流れない)
解決策
毎回、音源の再生時間を0
にすることで、連続でタップされても、毎回効果音を再生できる。
@objc func didTap() {
// 再生時間を最初に戻す
audioPlayer?.currentTime = 0
// 音源を再生する
audioPlayer?.play()
}
連続してタップしても、重複して再生されない。(前回の効果音を途中でキャンセルして、再び最初から流し始めるイメージ)
(e.g. 1秒で3回タップしても、3回とも効果音が再生される)
環境(2024/08/17)
以下の環境で検証しました。(これ以前の環境でも同じ現象が起こると思う)
- Xcode 15.3
- iOS 18
まとめ
AVAudioPlayer
のplay()
methodを呼ぶことで、Buttonをタップしたときに効果音を流す機能を実装できる。
素直にplay()
を呼ぶだけでは、連続でタップしたときに、直前のタップによる効果音が再生中なら、新たにタップしたときの効果音は再生されない。
play()
を呼ぶ前に、再生時間を0
にセットすることで、連続したタップでも、毎回、効果音を再生できる。(audioPlayer.currentTime = 0
)
Discussion