我的情况是,我recording
audio
和save
进入Coredata
,然后listing
进入tableView
,其中customcell
播放/暂停单个按钮。我不能做下面的事情
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
}
答案 0 :(得分:1)
在不了解应用程序其余部分的情况下很难解释。提供更多的上下文很重要。假设某些事情,我会尽力为您解答。
首先,我假设您有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!
}
外观如下:
接下来,让我们定义表视图的数据源方法。在每个单元格中,为每个按钮的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
}
接下来,让我们定义一个辅助方法,以在UIVIew
中定位TableView
。通过这种方法,我们可以获得IndexPath
中任何单元格内任何控件的TableView
。返回值是可选的,以便在找不到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)
}
}
以下是示例应用程序的视频片段:sample app