實作 Table View 功能 - Mamamoo成員 solo 歌曲列表
Published in
10 min readJan 21, 2022
HW #51 實作TableView的基本公能
這次嘗試模仿了 Spotify 的排版還有他的愛心功能,連圖片都是從 Spotify 上截圖的喔
下面是短短的 gif demo
私心附上有 mv 片段的 App錄屏
這個月,我的本命帶著快時隔兩年的solo 專輯回歸囉 ! 主打歌又是我超愛的psycho 主題,快點擊下面一起欣賞超好聽的音樂 (到底是哪一個psycho 可以上一秒可愛下一秒又那麼帥氣啦 !!!!!)
建立客製化的 TableViewCell
- 把 TableViewCell 換成custom 並幫他取一個 identifier
- 在裡面放好想要的物件後,建一個 subclass 是 UITableViewCell 的file 幫物件拉 IBOutlet
幫放進cell裡的資料建立 struct
- like variable 決定有沒有按愛心按鈕,會隨著使用者操作變換,所以 like, 裝有 songInfo 的 songList, 和裝有singerInfo 的 playList都要用 var
struct songInfo{
let singerName :String
let songTitle: String
let imageName : String
let url : String
var like : Bool
}struct singerInfo {
let singerName :String
var songList : Array<songInfo>
}
- 再以套娃的方式把每一個歌手的資料放進Array裡,就能擁有 section 和 row 資料
設定要有幾個section 和 row
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return playList.count
}override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return playList[section].songList.count
}
連結到tableViewController
把之前幫 tableViewCell 取的 identifier 放進 dequeueReusableCell(withIdentifier: propertyKey.songCell, for: indexPath) 然後用 as?轉成 剛剛幫tableViewCell 建立的class
struct propertyKey {
static let songCell = "songCell"
}override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: propertyKey.songCell, for: indexPath) as? playListTableViewCell else {return UITableViewCell()}let song = playList[indexPath.section].songList[indexPath.row]
cell.singerLabel.text = song.singerName
cell.songTitleLabel.text = song.songTitle
cell.songImageView.image = UIImage(named: song.imageName) if song.like == true {
cell.heartButton.setImage(UIImage(systemName: "heart.fill"), for: .normal)
cell.heartButton.tintColor = .green
}else {
cell.heartButton.setImage(UIImage(systemName: "heart"), for: .normal)
cell.heartButton.tintColor = .lightGray
}
return cell
}
模仿 Spotify 設定愛心按鈕
- 因為 tableViewCell 會重複利用 (dequeueReusableCell),所以按完按鈕後,要將改變後的值存回 songInfo,不然會複製到後面的 cell
- 用下面的方把找到按鈕在 tableView 上的座標,並對應得到第幾個row,在把值案照row number 給存回 songInfo
let point = sender.convert(CGPoint.zero, to: tableView)
if let indexPath = tableView.indexPathForRow(at: point){
...
}@IBAction func heartButtonChange(_ sender: UIButton) {
let point = sender.convert(CGPoint.zero, to: tableView)
if let indexPath = tableView.indexPathForRow(at: point){
if sender.imageView?.image == UIImage(systemName: "heart"){
playList[indexPath.section].songList[indexPath.row].like = true
sender.setImage(UIImage(systemName: "heart.fill"), for: .normal)
sender.tintColor = .green
} else if sender.imageView?.image == UIImage(systemName: "heart.fill"){
playList[indexPath.section].songList[indexPath.row].like = false
sender.setImage(UIImage(systemName: "heart"), for: .normal)
sender.tintColor = .lightGray
}
}
}
幫每個section 設定header
- 設定 section 裡的內容
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return playList[section].singerName
}
- 設定背景顏色還有字型
override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let headerView = view as! UITableViewHeaderFooterView
headerView.contentView.backgroundColor = .black
headerView.textLabel?.textColor = .white
headerView.textLabel?.font = .systemFont(ofSize: 26, weight: .bold)
headerView.textLabel?.sizeToFit()
}
- 設定header 的高度
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}}
用IBSegueAction 將要傳的資料傳過去
- Segue 要從 table cell 連到下一個View (不是從 View 連到下一個 View )
@IBSegueAction func showWebSite(_ coder: NSCoder) -> playListWebViewController? {
guard let section = tableView.indexPathForSelectedRow?.section else {return nil}
guard let row = tableView.indexPathForSelectedRow?.row else {return nil}
let song = playList[section].songList[row]
return playListWebViewController(coder: coder, song: song)
}
顯示對應的 YouTube MV 網頁
- 將WebView 連IBOutlet
- 記得要 import WebKit
@IBOutlet weak var youtubeWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: URL(string: song.url)!)
youtubeWebView.load(request)
}