仿 iOS Music App (基本題)
播放, 暫停, 上 / 下首, 調整音量
成品:Gif / 影片,因 #FreeBritney 朋友提議選我們懶妮做主題
▲這幾年西音全是莫名怪 Rap 便聽日文為主,這次回歸馬上陷音樂漩渦
▲我們那年代真的超全盛爆多 icon 的啦!一回味半天就掰了😅
▲最後精選和懶妮合演 / 作過 4 大咖 / 金曲及她出道曲
▲本想挑戰進階題但搞不懂 addPeriodicTimeObserver() 只好放棄
▲沒音樂時間顯示和 Slider 軌跡有夠怪還不能拉區段,但我太嫩沒辦法
▲音樂時間等程式很多也很難,看蘋果 Documentation 時會瞬間變文盲
前置作業
▲找歌與專輯封面,我有 CD 但 Mac 沒光碟機無法直接放檔案也是好笑
▲ Storyboard 版面配置,因只有基本題其他功能 (圖) 就先刪掉不放
▲ iphone 原圖背景是封面其中幾色漸層,但彼得說那要另套件再寫程式
▲背景一樣放封面選擇毛玻璃效果 Visual Effect View with Blur (Library)
▲ button 怕之後做進階題有需要,皆把圖放 background 非一般 image
有音樂所以加入 AVFoundation 函式庫 (framework)
import AVFoundation
新增 Swift File 用
struct
定義 Single 型別
struct Single {
let song: String!
let singer: String!
let albumCover: String!
}
拉 IBOutlet
@IBOutlet weak var backgroundImageView: UIImageView!
@IBOutlet weak var albumCoverImageView: UIImageView!@IBOutlet weak var songLabel: UILabel!
@IBOutlet weak var singerLabel: UILabel!@IBOutlet weak var volumeSlider: UISlider!@IBOutlet weak var playPauseButton: UIButton!
宣告:單曲資訊 Array, AVPlayer 型別的 property player
var singles = [Single]()
var index = 0
var player = AVPlayer()
初始畫面:封面圓角,Slider 指標圖 (自己做小圓球),單曲各資訊
override func viewDidLoad() {
super.viewDidLoad() albumCoverImageView.layer.cornerRadius = 13 volumeSlider.setThumbImage(UIImage(named: “thumb2”), for:
.normal) singles = [
Single(song: “…Baby One More Time”, singer: “Britney
Spears”,albumCover: “britney”),
Single(song: “The Way You Make Me Feel”, singer: “Michael
Jackson”, albumCover: “MJ”),
Single(song: “Hollywood”, singer: “Madonna”, albumCover:
“madonna”),
Single(song: “I Want It That Way”, singer: “Backstreet
Boys”,albumCover: “backstreet boys”),
Single(song: “S&M”, singer: “Rihanna”, albumCover:
“rihanna”)
]
}
定義 playMusic():單曲資訊 / 播放歌曲依 index 改變,按鍵為 pause
func playMusic(){
backgroundImageView.image = UIImage(named:
singles[index].albumCover)
albumCoverImageView.image = UIImage(named:
singles[index].albumCover) songLabel.text = singles[index].song
singerLabel.text = singles[index].singer let fileUrl = Bundle.main.url(forResource: singles[index].singer,
withExtension: “mp3”)!
let playerItem = AVPlayerItem(url: fileUrl)
player.replaceCurrentItem(with: playerItem)
player.play() playPauseButton.setBackgroundImage(UIImage(systemName:
“pause.fill”), for: .normal)
}
拉 IBAction
@IBAction func playNPause(_ sender: Any) {
}
@IBAction func nextSong(_ sender: Any) {
}
@IBAction func PreviousSong(_ sender: Any) {
}
@IBAction func changeVolume(_ sender: UISlider) {
}
播放 / 暫停
▲首個條件一直想不出來直到彼得幫忙,player.currentItem 我記得你了
▲除 player.rate = 0 也可用 player.timeControlStatus = .paused / .playing
▲續播不用 player.play() 也可用 player.seek(to: player.currentTime())
▲有 player.play() 當然也有 player.pause(),1 個播 1 個停
@IBAction func playNPause(_ sender: Any) {
if player.currentItem == nil {
playMusic() } else if player.rate == 0 {
playPauseButton.setBackgroundImage(UIImage(systemName:
“pause.fill”), for: .normal) player.play() } else {
playPauseButton.setBackgroundImage(UIImage(systemName:
“play.fill”), for: .normal) player.pause()
}
}
下一首:簡單寫法是使用餘數,也可用下面上一首類似寫法
@IBAction func nextSong(_ sender: Any) {
index = (index + 1) % singles.count playMusic()}
上一首:注意 Array.count 是總數,和陣列裡編號不一樣,所以要 -1
@IBAction func PreviousSong(_ sender: Any) {
index -= 1 if index < 0 {
index = singles.count — 1
playMusic() } else {
playMusic()
}
}
調整音量:2 種方法
▲直接用 slider value 代入,手法粗糙
@IBAction func changeVolume(_ sender: UISlider) {
player.volume = sender.value}
▲實際調整系統音量 (下為彼得例子)
➞先加 import MediaPlayer,然後在畫面上加入 MPVolumeView
➞只能在實機測試,模擬器無法
let volumeView = MPVolumeView(frame: CGRect(x: 10, y: 100, width: 300, height: 40))view.addSubview(volumeView)
完整程式碼:上半部為 Single (struct),下半部為 ViewController
參考來源