gpt4 book ai didi

ios - 如何判断我是否使用同一项来填充多个 UICollectionViewCell?

转载 作者:行者123 更新时间:2023-11-30 11:09:00 25 4
gpt4 key购买 nike

我正在开发一个音乐应用程序,用户可以浏览精选的轨道并将它们保存到播放列表中。我遇到一个问题,如果一个轨道被保存到播放列表中两次,一次在另一个之后,播放控件不会按预期工作,即 2x track1 被添加到播放列表的开头 - 如果选择第一个 track1 - 播放和暂停好的,那么如果我选择第二个轨道 1(如果已经选择了第一个轨道 1,反之亦然),它将继续播放/暂停,就好像它是第一个轨道 1 一样。

有没有办法复制该项目而不是引用相同的项目?下面是一些代码,显示了我如何填充播放列表和数据结构等。

数据结构:

class Data: NSObject, NSCoding {

var title: String
var body: String
var colour: UIColor
var url: String
var isPlaying : Bool = false

init(title: String, body: String, colour: UIColor, url: String) {
self.title = title
self.body = body
self.colour = colour
self.url = url
}

class func createTrackArray() -> [Data] {
var array: [Data] = []

let track1 = Data(title: "Track 1 Title", body: "Track 1 Body", colour: .white, url: "track1url")
let track2 = Data(title: "Track 2 Title", body: "Track 2 Body", colour: .white, url: "track2url")

array.append(track1)

return array
}

}

显示要浏览的音乐:

//Global Variable
var musicDataArray: [Data] = []

class MusicVC: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

musicDataArray = Data.createTrackArray()
}

}

//MARK: - CollectionView Cell Configuration

extension MusicVC: UICollectionViewDelegate, UICollectionViewDataSource, CellDelegate {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return musicDataArray.count
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: .musicCell, for: indexPath) as! MusicCell

cell.cellData = musicDataArray[indexPath.item]
cell.song = musicDataArray[indexPath.item]

cell.cellDelegate = self
return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

currentIndexPathItem = indexPath.item

guard let cellToPlay = musicCollectionView.cellForItem(at: IndexPath(item: currentIndexPathItem, section: 0)) as? MusicCell else {
print("Cell not here")
return
}
didSelectCell(for: cellToPlay)

prepareTrackForSavingToPlaylist(track: indexPath.item)
}

func didSelectCell(for cell: MusicCell) {
cell.play()
}

该函数将索引(和关联的数组项??)保存到临时数组中。然后我通过 segue 将其发送到另一个 View Controller ,从而将其保存到播放列表中。即 playlistArray 中只会有一个项目传递给下一个 View Controller 。

func prepareTrackForSavingToPlaylist(track: Int) {
playlistArray.removeAll()
playlistArray.append(musicDataArray[track])
}

下一个 View Controller :传递的数据(来自前一个 View Controller 的临时数组的信息)然后添加到他们在 Collection View 中选择的任何播放列表中

 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

let passedData = Data(title: dataFromMusicVC.title, body: dataFromMusicVC.body, colour: dataFromMusicVC.colour, url: dataFromMusicVC.url)
playlistArray[indexPath.item].append(passedData)
}

最后用户可以选择一个播放列表,它将显示该播放列表中所有已保存的轨道

extension UserPlaylistsVC: UICollectionViewDelegate, UICollectionViewDataSource, UserDelegate {

func didSelectCell(for cell: UserPlaylistsCell) {
cell.play()
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return playlistArray[playlistIndex].count
}

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let createID = "UserCell"
let userCell = collectionView.dequeueReusableCell(withReuseIdentifier: createID, for: indexPath) as! UserPlaylistsCell

//playlistIndex is just an Int that is based on which cell is selected in a different view controller so that the right playlist is accessed.
userCell.song = playlistArray[playlistIndex][indexPath.item]
userCell.cellData = playlistArray[playlistIndex][indexPath.item]

userCell.userDelegate = self
userCell.delegate = self

return userCell
}

这是用于播放列表中轨道的单元格:

    protocol UserDelegate: class {
func didSelectCell (for cell: UserPlaylistsCell)
}

class UserPlaylistsCell: UICollectionViewCell {

@IBOutlet weak var titleLbl: UILabel!
@IBOutlet weak var bodyLbl: UILabel!
@IBOutlet weak var colourView: UIView!

var song : TypeData!
var audio = Audio()

weak var delegate: UserPlaylistDelegate?
weak var userDelegate: UserDelegate?

override func prepareForReuse() {
super.prepareForReuse()
}

override var isSelected: Bool {
didSet {
self.contentView.backgroundColor = isSelected ? UIColor.UMLightGrey : UIColor.white
}
}

override func awakeFromNib() {
super.awakeFromNib()

titleLbl.textColor = UIColor.UMDarkGrey
bodyLbl.textColor = UIColor.UMDarkGrey
colourView.layer.cornerRadius = colourView.layer.frame.size.width / 2
colourView.clipsToBounds = true
}

var cellData: TypeData! {
didSet {
titleLbl.text = cellData.title
bodyLbl.text = cellData.body
colourView.backgroundColor = cellData.colour
}
}

func play() {

if !(song?.isPlaying)! {
song?.isPlaying = true

//Checking whether the global variable is the same as the selected song url so that I don't have to fetch the asset again (fetching the asset plays the track from the beginning again)

if urlString == song.url {
player.play()
} else {
urlString = song.url
audio.fetchAsset()
audio.playAsset()
}
return
}

song?.isPlaying = false
player.pause()

print("Stop", (song?.title)!)
}

}

您是否知道为什么如果同一轨道连续两次保存到播放列表中并被选择播放 - 控件的行为不会像它是不同的轨道一样,即所需的功能是它会被视为完全不同的轨道,选择它会再次从头开始播放,同时还保留单独暂停和播放它们的能力。

如果您需要更多说明或额外代码,请随时询问。我真的很感谢您花时间研究这个问题。

编辑

这是请求的 didSelectItemAt 方法:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

currentItemIndex = indexPath.item

guard let cellToPlay = userPlaylistsCollectionView.cellForItem(at: IndexPath(item: currentItemIndex, section: 0)) as? UserPlaylistsCell else {
return
}

didSelectCell(for: cellToPlay)
}

编辑

didDeselect方法:

    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {

if let cellToStop = userPlaylistsCollectionView.dataSource?.collectionView(userPlaylistsCollectionView, cellForItemAt: indexPath) as? UserPlaylistsCell {
if (cellToStop.song.isPlaying) {
didSelectCell(for: cellToStop)
print(cellToStop.song.isPlaying)
}
}
}

最佳答案

问题可能出在这里

if urlString == song.url {
player.play()
} else {
urlString = song.url
audio.fetchAsset()
audio.playAsset()
}

这是基于以下事实:两首歌曲具有不同的 url,但如果轨道相同,则它们肯定具有相同的 url。尝试不同的缓存系统,例如包含先前/当前播放/正在播放的歌曲 ID 的数组(例如,基于单元格索引路径)。

无论如何,让用户在播放列表中多次使用同一轨道是一种不好的行为。

关于ios - 如何判断我是否使用同一项来填充多个 UICollectionViewCell?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52383815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com