簡體   English   中英

如何使用 Swift 處理 tableView 單元格音頻播放和暫停按鈕?

[英]How to handle tableView cell audio play and pause button using Swift?

在我的場景中,我正在recording audiosaveCoredata然后使用customcell播放/暫停單個按鈕listing tableView 我不能做下面的事情

  1. 檢測playback結束並更改audio play單元格按鈕圖像暫停播放
  2. 在第一行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
}

接下來讓我們定義一個輔助方法來定位TableViewUIVIew 使用這種方法,我們可以獲取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方法。 邏輯如下:

  1. 使用 helper 方法在表視圖中本地化按鈕的IndexPath
  2. 將數據庫中的歌曲本地化,表中的行號對應數據庫中的順序。
  3. 如果當前正在播放一首歌曲並且與點擊按鈕的本地化相同,則表示我們只想停止播放歌曲,因此stopCurrentlyPlaying並返回該方法。
  4. 如果不是同一首歌曲或沒有播放讓我們調用: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM