質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

3254閲覧

【Swift,Xcode】再生中の曲の位置をスライダーのアニメーションで示したい

nekokichi

総合スコア54

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1グッド

1クリップ

投稿2018/09/23 08:02

編集2018/09/23 08:54

イメージ説明

↓シミュレータの動画です
https://twitter.com/nekokichi1_yos2/status/1043785383253749760

既存の音楽プレイヤーみたいに、曲が再生してる時、スライダーが曲の再生位置を示すように、徐々に右へ動いていくアニメーションを実装したいです。

そのために、
・timer関数を作成
・update関数(musicplayer.currenttimeをスライダーのvalueにセット)
・timer関数でupdate関数を1.0秒ごとに処理
という流れを組みました。

しかし、曲を再生してもスライダーは動かず、一時停止し、再び曲を再生すると、いきなりスライダーがスーッと曲の現在位置に動き出します。

ですが、その後は動かず、また一時停止→再生を繰り返しても、同じことが続きます。

おそらく、スライダーとmusicplayerがうまく同期してないのが原因だと思うのですが、下記のコード内にどこか問題点があれば、ご指摘願います。

Swift

1import UIKit 2import AVFoundation 3 4class PlayViewController: UIViewController { 5 6 //再生中か一時停止中かを判定 7 //1:play 0:pause 8 var playorpause = -1 9 //プレイヤーの現在地 10 var currentTime = 0.0 11 12 var songtext = "" 13 var artisttext = "" 14 var imagetext = "" 15 var songfiletext = "" 16 17 var musicplayer = AVAudioPlayer() 18 var musicPath = Bundle.main.bundleURL.appendingPathComponent("") 19 20 //スライダーと曲を連動させるタイマー 21 var timer = Timer() 22 23 @IBOutlet weak var songnameLabel: UILabel! 24 25 @IBOutlet weak var artistLabel: UILabel! 26 27 @IBOutlet weak var imageView: UIImageView! 28 29 @IBOutlet weak var playButton: UIButton! 30 31 @IBOutlet weak var scrubSlider: UISlider! 32 33 override func viewDidLoad() { 34 super.viewDidLoad() 35 36 songnameLabel.text = songtext 37 artistLabel.text = artisttext 38 imageView.image = UIImage(named: imagetext) 39 musicPath = Bundle.main.bundleURL.appendingPathComponent(songfiletext) 40 41 42 // Do any additional setup after loading the view. 43 } 44 45 @IBAction func scrub(_ sender: Any) { 46 //ピンを置いた箇所を再生箇所として設定 47 musicplayer.currentTime = TimeInterval(scrubSlider.value) 48 } 49 50 @IBAction func playAction(_ sender: Any) { 51 52 switch playorpause { 53 case -1: 54 createplayer() 55 playorpause = 1 56 case 0: 57 playplayer() 58 playorpause = 1 59 case 1: 60 pauseplayer() 61 playorpause = 0 62 default: 63 break 64 } 65 66 67 } 68 69 @IBAction func backAction(_ sender: Any) { 70 } 71 72 @IBAction func nextAction(_ sender: Any) { 73 } 74 75 @IBAction func volumeUp(_ sender: Any) { 76 if musicplayer.volume <= 1.0 { 77 musicplayer.volume += 0.1 78 } 79 print(musicplayer.volume) 80 } 81 82 @IBAction func volumeDown(_ sender: Any) { 83 if musicplayer.volume > 0.1 { 84 musicplayer.volume -= 0.1 85 } 86 print(musicplayer.volume) 87 } 88 89 //スライダーの現在位置を曲の再生位置に指定 90 @objc func updateTime() { 91 UIView.animate(withDuration: 1.0, animations: { 92 self.scrubSlider.setValue(Float(self.musicplayer.currentTime), animated: true) 93 }) 94 } 95 96 //プレイヤーを作成する 97 func createplayer() { 98 do { 99 musicplayer = try AVAudioPlayer(contentsOf: musicPath, fileTypeHint: nil) 100 //スライダーの長さを音楽長さに同期する 101 scrubSlider.maximumValue = Float(musicplayer.duration) 102 timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: false) 103 playButton.setImage(UIImage(named: "pause.png"), for: UIControl.State()) 104 musicplayer.play() 105 } catch { 106 print("エラーが起きました") 107 } 108 } 109 110 //プレイヤーを再生する 111 func playplayer() { 112 musicplayer.play() 113 musicplayer.currentTime = currentTime 114 if timer.isValid == false { 115 timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: false) 116 } 117 playButton.setImage(UIImage(named: "pause.png"), for: UIControl.State()) 118 } 119 120 //プレイヤーを停止する 121 func pauseplayer() { 122 musicplayer.pause() 123 currentTime = musicplayer.currentTime 124 timer.invalidate() 125 playButton.setImage(UIImage(named: "play.png"), for: UIControl.State()) 126 } 127 128 129}
DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

とりあえず、scheduledTimerで、repeatをtrueに設定してみてください。

投稿2018/09/23 15:49

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問