首页 > 解决方案 > 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
 }

问题

  1. 如果用户单击另一个单元格,我想隐藏播放按钮,只有正在播放当前歌曲的单元格会显示按钮(它用于播放或停止)但问题是按钮显示在单元格的每一行上我也没有如果我再次单击正在播放的歌曲单元格,我不想隐藏按钮。

  2. 如果用户点击单元格,根据单元格编号,它将始终播放同一首歌曲,我想根据单元格编号播放 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

标签: iosswiftuitableviewavfoundationavaudioplayer

解决方案


推荐阅读