swiftでUISwitchを押すと指定の時間にアラームが鳴るアプリを作っています。指定時間にちゃんと鳴るのですが
UISwitchをオフにした時にストップするようにしたいです。下記のコードだと40秒後くらいにオフにしなくても自動でアラームがストップしてしまいます。自分でもelse以下にself.audioPlayer.stop()と書いてみたのですがうまくいきませんどなたか知恵をお借りできたら幸いです。よろしくお願い申し上げます。
swift
1import UIKit 2import AVFoundation 3 4class SecondViewController: UIViewController,AVAudioPlayerDelegate, UITableViewDelegate, UITableViewDataSource{ 5 6 //追加② 7 let TODO = ["15分後", "30分後", "45分後"] 8 9 var timer = Timer() 10 var startTime:Double = 0.0 11 var audioPlayer: AVAudioPlayer! 12 @IBOutlet weak var tableView: UITableView! 13 @IBAction func `switch`(_ sender: UISwitch) 14 { 15 if (sender.isOn) { 16 //switchがonならtimer起動 17 timer = Timer.scheduledTimer(withTimeInterval: 1 * 2, repeats: true, block: { timer in 18 //15分後にアラーム鳴る 19 self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 1 * 2) 20 }) 21 } else { 22 //offならtimer停止 23 timer.invalidate() 24 print("stopped") 25 self.audioPlayer.stop() 26 } 27 } 28 @IBAction func switch2(_ sender: UISwitch) 29 { 30 if (sender.isOn) { 31 //switchがonならtimer起動 32 timer = Timer.scheduledTimer(withTimeInterval: 60 * 30, repeats: true, block: { timer in 33 //15分後にアラーム鳴る 34 self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 60 * 30) 35 }) 36 } else { 37 //offならtimer停止 38 timer.invalidate() 39 print("stopped") 40 self.audioPlayer.stop() 41 } 42 } 43 @IBAction func switch3(_ sender: UISwitch) 44 { 45 if (sender.isOn) { 46 //switchがonならtimer起動 47 timer = Timer.scheduledTimer(withTimeInterval: 60 * 45, repeats: true, block: { timer in 48 //15分後にアラーム鳴る 49 self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 60 * 45) 50 }) 51 } else { 52 //offならtimer停止 53 timer.invalidate() 54 print("stopped") 55 self.audioPlayer.stop() 56 } 57 } 58 59 60 override func viewDidLoad() { 61 super.viewDidLoad() 62 63 if let url=Bundle.main.url(forResource:"1",withExtension:".mp3" ){ 64 //上記の***の箇所でファイル名と拡張子を指定し変数urlに代入します。 65 do { 66 audioPlayer=try AVAudioPlayer(contentsOf:url) 67 audioPlayer?.play(atTime:1 * 10) 68 //処理が成功したらaudioPlayerに指定したurlを代入し、playメソッドを呼び出します。 69 }catch{ 70 audioPlayer=nil 71 } 72 }else{ 73 fatalError("Url is nil") 74 //URLが空の場合など処理が走らなかった場合はエラー文を表示します。 75 } 76 audioPlayer.delegate = (self as AVAudioPlayerDelegate) 77 audioPlayer.prepareToPlay() 78 79 } 80 81 override func didReceiveMemoryWarning() { 82 super.didReceiveMemoryWarning() 83 // Dispose of any resources that can be recreated. 84 } 85 //追加③ セルの個数を指定するデリゲートメソッド(必須) 86 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 87 return TODO.count 88 } 89 90 //追加④ セルに値を設定するデータソースメソッド(必須) 91 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 92 // セルを取得する 93 let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 94 // セルに表示する値を設定する 95 cell.textLabel!.text = TODO[indexPath.row] 96 return cell 97 } 98}
基本的な所から確認なのですがそのmp3ファイルの曲の長さは40秒程度、ということはないですか?
map3の長さは15秒でコード内でreapeats: trueにしてるので3回ほど再生(再再生される間に2秒程のタイムラグがありそれも出来れば直したいです)されたのち、止まってしまいます.
mp3ファイルの長さの件了解しました。
そのタイムラグがあるのって`switch`関数ではないですか?
後viewDidLoad()内にあるaudioPlayer.delegate = (self as AVAudioPlayerDelegate) この部分、audioPlayer.delegate = selfで良さそうです。
例にもれず最小構成で上記のコードと同じようなものを作ったのですが普通にリピートしてくれてますね。
とりあえず`switch`関数内のself.audio.player(atTime:)の一行下にprint(self.audioPlayer.isPlaying)を書いてください。そしてその結果を教えてください。
スイッチを押し12秒ほどで停止→2秒後にリピート開始 この動作を5回程確認しました ありがとうございます永遠にリピートされそうです。欲を言うとリピートする間の2秒程のタイムラグを無くすことはできるでしょうか?
self.audioPlayer.play(atTime:self.audioPlayer.deviceCurrentTime + 1 * 2) 多分これがタイムラグの原因じゃないかな。self.audioPlayer.play()に書き換えて試してみてください。
スムーズになりましたがdebugで見た時の9回目の true表示の時に鳴りません。でも以前よりだいぶスムーズになりました(特にUISwitchをオンにした瞬間のタイムラグがなくなりました)
リファレンス流し読みなのですがタイムラグは.play(atTime:)で任意の時間を設定する時に使うようですね。今日はもう遅いので明日またデバッグにお付き合いします。
回答1件
あなたの回答
tips
プレビュー