[英]How to handle tableView cell audio play and pause button using Swift?
在我的場景中,我正在recording
audio
並save
到Coredata
然后使用customcell
播放/暫停單個按鈕listing
tableView
。 我不能做下面的事情
playback
結束並更改audio
play
單元格按鈕圖像暫停播放cell
音頻播放時間,如果用戶點擊第二行播放按鈕需要stop
第一行單元格音頻播放並更改圖像暫停播放然后second row
單元格按鈕播放暫停以上兩個操作怎么做?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CustomCell
// Configure the cell...
cell.likeBtn.addTarget(self, action: #selector(TableViewController.liked), for: .touchUpInside)
return cell
}
@objc func liked(sender: UIButton) {
// Here I need to change button icon and handle row
}
如果不了解應用程序的其余部分,就很難解釋。 提供更多背景信息很重要。 假設某些事情,我會盡量給你一個答案。
首先,我假設您有如下所示的Song
對象:
public struct Song: Equatable {
let name: String
let fileName: String
}
您的數據庫具有以下公共方法和屬性:
class DB {
func getSong(_ position: Int) -> Song?
func getPosition(_ song: Song) -> Int?
var count: Int
}
為了使init
上的示例代碼更容易,一些預定義數據被初始化。
還有一個Player
對象,它使用以下公共方法管理播放音頻:
class Player {
func currentlyPlaying() -> Song?
func play(this song: Song)
func stop()
}
現在使用之前定義的這個,我創建了一個自定義單元格來顯示數據庫中每首Song
的名稱和按鈕。 定義是這樣的:
class CustomCell : UITableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var button: UIButton!
}
看起來像:
接下來讓我們定義 tableview 的數據源方法。 在每個單元格中,為每個按鈕的 touchUpInside 事件添加一個目標(如您在問題中定義的那樣)。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return DB.shared.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell",
for: indexPath) as! CustomCell
cell.label.text = DB.shared.getSong(indexPath.row)!.name
cell.button.addTarget(self, action: #selector(buttonTapped(_:)),
for: .touchUpInside)
return cell
}
接下來讓我們定義一個輔助方法來定位TableView
的UIVIew
。 使用這種方法,我們可以獲取TableView
任何單元格內任何控件的IndexPath
。 返回值是可選的,以便在未找到時返回nil
。
func getViewIndexInTableView(tableView: UITableView, view: UIView) -> IndexPath? {
let pos = view.convert(CGPoint.zero, to: tableView)
return tableView.indexPathForRow(at: pos)
}
另一個輔助方法定義為使用動畫更改按鈕的圖像:
func changeButtonImage(_ button: UIButton, play: Bool) {
UIView.transition(with: button, duration: 0.4,
options: .transitionCrossDissolve, animations: {
button.setImage(UIImage(named: play ? "Play" : "Stop"), for: .normal)
}, completion: nil
}
需要一種方法來停止任何當前正在播放的歌曲。 第一件事是檢查歌曲是否正在播放,如果是,則調用Player
的 stop 方法。 然后讓我們定位Song
在數據庫中的位置,在我的例子中對應於TableView
的位置; 有了這個,讓我們創建一個 IndexPath 來獲取相應的單元格,最后使用單元格的按鈕調用changeButtonImage
來更改圖像。
func stopCurrentlyPlaying() {
if let currentSong = Player.shared.currentlyPlaying() {
Player.shared.stop()
if let indexStop = DB.shared.getPosition(currentSong) {
let cell = tableView.cellForRow(at: IndexPath(item: indexStop, section: 0)) as! CustomCell
changeButtonImage(cell.button, play: true)
}
}
}
開始播放歌曲的buttonTapped
方法內部有一些邏輯。 首先,方法簽名需要@objc
為了在使用addTarget
方法。 邏輯如下:
IndexPath
。stopCurrentlyPlaying
並返回該方法。stopCurrentlyPlaying
,開始播放新歌曲並將點擊按鈕的圖像更改為停止圖像。代碼如下所示:
@objc func buttonTapped(_ sender: UIButton) {
// Let's localize the index of the button using a helper method
// and also localize the Song i the database
if let index = getViewIndexInTableView(tableView: tableView, view: sender),
let song = DB.shared.getSong(index.row) {
// If a the song located is the same it's currently playing just stop
// playing it and return.
guard song != Player.shared.currentlyPlaying() else {
stopCurrentlyPlaying()
return
}
// Stop any playing song if necessary
stopCurrentlyPlaying()
// Start playing the tapped song
Player.shared.play(this: song)
// Change the tapped button to a Stop image
changeButtonImage(sender, play: false)
}
}
這是示例應用程序工作的一個小視頻:示例應用程序
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.