ios - Swift AVAudioPlayer 没有停止歌曲,并且按钮在离开 UITable View 时没有消失
问题描述
在过去的两周里,我一直在努力解决 2 个问题并且找不到解决方案,在音频播放器上工作,当 UItableview 单元格单击或里面的按钮单击播放按钮时,我想在其中播放音频文件所以我创建了一个带有音频细节的结构,我稍后计划从 mp3 文件中提取,如歌曲名称、艺术家持续时间等,但现在我对这些细节进行硬编码,以便我的主要重点是在单元格点击或按钮上播放歌曲
struct Audio {
let id: Int
let trackName: String
let trackTitle: String
let creationDate = Date()
let album: String
let uploadedBy: String
let genre: String
let lyricsLang: String
let artist: String
let duration: Float
var completed = false
}
问题
如果用户单击另一个单元格,我想隐藏播放按钮,只有正在播放当前歌曲的单元格会显示按钮(它用于播放或停止)但问题是按钮显示在单元格的每一行上我也没有如果我再次单击正在播放的歌曲单元格,我不想隐藏按钮。
如果用户点击单元格,根据单元格编号,它将始终播放同一首歌曲,我想根据单元格编号播放 0.mp3、1.mp3、2.mp3、3.mp3 等歌曲,以及如果我在播放下一首歌曲或试图离开单元格之前尝试停止歌曲,则停止按钮不起作用下面是我的整个代码
class AudioListViewController: UIViewController { var selectedRowIndex = -1 var songList: [Audio] = [ Audio(id: 0, trackName: "Song 1", trackTitle: "ABbcd:", album: "Loreim loreim", uploadedBy: "A men", genre: "Romantic", lyricsLang: "English", artist: "God", duration: 2.00), Audio(id: 1, trackName: "Song 2", trackTitle: "ABbcd:", album: "Loreim loreim", uploadedBy: "A men", genre: "Romantic", lyricsLang: "English", artist: "God", duration: 2.00), Audio(id: 2, trackName: "Song 3", trackTitle: "ABbcd:", album: "Loreim loreim", uploadedBy: "A men", genre: "Romantic", lyricsLang: "English", artist: "God", duration: 2.00) ] @IBOutlet weak var songListTableView: UITableView! var isTapped: Bool = false @IBOutlet weak var close: UIButton! override func viewDidLoad() { super.viewDidLoad() songListTableView.dataSource = self songListTableView.delegate = self title = "Back" navigationItem.backButtonTitle = "Back be?" songListTableView.register(UINib(nibName: "SongsListTableViewCell", bundle: nil), forCellReuseIdentifier: "SongListCell") } @IBAction func closeSe(_ sender: Any) { self.dismiss(animated: true, completion: nil) } } extension AudioListViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return songList.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SongListCell", for: indexPath) as! SongsListTableViewCell cell.songTitle?.text = songList[indexPath.row].trackName cell.songDuration?.text = String(songList[indexPath.row].duration) return cell } } extension AudioListViewController: UITableViewDelegate{ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) let position = indexPath.row print(indexPath.row) let vc = tableView.dequeueReusableCell(withIdentifier: "SongListCell", for: indexPath) as! SongsListTableViewCell vc.songs = songList vc.position = position let selectedFilterRow = songList[indexPath.section].id if selectedFilterRow == indexPath.row { return } if let previousCell = tableView.cellForRow(at: IndexPath(row: selectedFilterRow, section: indexPath.section)) { vc.useSong.isHidden = true vc.useSong.alpha = 0 vc.stopSong() } if let cell = tableView.cellForRow(at: indexPath) { vc.useSong.isHidden = true vc.useSong.alpha = 0 vc.stopSong() vc.configure(position: position) } } }
现在可以点击获取歌曲文件名,以及单元格的其他功能
class SongsListTableViewCell: UITableViewCell {
public var songs: [Audio] = [
Audio(id: 0, trackName: "Song 1", trackTitle: "ABbcd:", album: "Loreim loreim",
uploadedBy: "A men", genre: "Romantic", lyricsLang: "English", artist: "God",
duration: 2.00),
Audio(id: 1, trackName: "Song 2", trackTitle: "ABbcd:", album: "Loreim loreim",
uploadedBy: "A men", genre: "Romantic", lyricsLang: "English", artist: "God",
duration: 2.00),
Audio(id: 2, trackName: "Song 3", trackTitle: "ABbcd:", album: "Loreim loreim",
uploadedBy: "A men", genre: "Romantic", lyricsLang: "English", artist:
"God", duration: 2.00) ]
public var position: Int = 0
public var isPlaying: Bool = false
var cellsState: Bool = false
var songPlayer: AVAudioPlayer?
@IBOutlet weak var singleViewCell: UIStackView!
@IBOutlet weak var songCellView: UIView!
@IBOutlet weak var songImage: UIImageView!
@IBOutlet weak var songTitle: UILabel!
@IBOutlet weak var songDuration: UILabel!
@IBOutlet weak var makeFavorite: UIButton!
@IBOutlet weak var useSong: UIButton!
let songReoad: AudioListViewController! = nil
override func awakeFromNib() {
super.awakeFromNib()
useSong.addTarget(self, action:
#selector(SongsListTableViewCell.selectSong(_:)), for: .touchUpInside)
makeFavorite.addTarget(self, action:
#selector(SongsListTableViewCell.makeFavourite(_:)), for: .touchUpInside )
useSong.isHidden = true
}
private let albumNameLabel: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.numberOfLines = 0 // line wrap
return label
}()
private let artistNameLabel: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.numberOfLines = 0 // line wrap
return label
}()
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
useSong.layer.cornerRadius = 6
configure(position: self.position)
}
func configure(position:Int) {
let song = songs[position]
let songId = String(song.id)
let urlString = Bundle.main.path(forResource: songId, ofType: "mp3")
do {
try AVAudioSession.sharedInstance().setMode(.default)
try AVAudioSession.sharedInstance().setActive(true, options:
.notifyOthersOnDeactivation)
guard let urlString = urlString else {
return
}
songPlayer = try AVAudioPlayer(contentsOf: URL(string: urlString)!)
guard let player = songPlayer else {
return
}
player.volume = 0.5
player.play()
isPlaying = true
}
catch {
print("error occurred")
}
songTitle.text = song.trackName
albumNameLabel.text = song.album
// Frame
let yPosition = artistNameLabel.frame.origin.y + 70 + 20
let size: CGFloat = 70
backButton.frame = CGRect(x: 20,
y: yPosition,
width: size,
height: size)
// Add actions
makeFavorite.addTarget(self, action: #selector(didTapPlayPauseButton), for:
.touchUpInside)
}
func stopSong(){
if let player = songPlayer {
player.stop()
}else{
songPlayer?.stop()
}
}
@IBAction func selectSong(_ sender: UIButton) {
cellsState = !cellsState
songPlayer?.stop()
if (cellsState) {
useSong.isHidden = false
useSong.alpha = 1
UIView.animate(withDuration: 0.6,
animations: {
self.useSong.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
},
completion: { _ in
UIView.animate(withDuration: 0.6) {
self.useSong.transform = CGAffineTransform.identity
}
})
} else {
useSong.isHidden = true
useSong.alpha = 0
}
}
@IBAction func makeFavourite(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
if sender.isSelected {
makeFavorite.setImage(UIImage(systemName: "star.fill"), for: .normal)
} else {
makeFavorite.setImage(UIImage(systemName: "star"), for: .normal)
}
}
@objc func didTapPlayPauseButton() {
if songPlayer?.isPlaying == true {
// pause
songPlayer?.pause()
}
else {
// play
songPlayer?.play()
}
}
}
这就是它现在的样子 SongList 视图
这是我的Songlistview
解决方案
推荐阅读
- javascript - d3js 强制布局:节点和链接位置的空值
- c# - 如何在 Linq 查询中获取“命名”元组组件?
- angular - 路径未按预期在 tsconfig.json 中工作
- java - Android gradle 版本没有更新
- sql - 转换 json 字段的输入
- python-3.x - Python3 子进程和 if elif else 条件
- javascript - 弹出关闭图标点击事件自定义
- django - 如何使用一个应用程序中的 Django 模型连接到第二个应用程序的数据库副本?
- app-store - 上传我的应用程序时出错:App Sore Connect 操作错误
- android - 不同设备的布局 - 约束布局和最小宽度限定符