首页 > 解决方案 > 使用多个集合视图时单元格不会加载

问题描述

我有两个集合视图,它们从两个从 url 会话函数附加的数组中获取数据。我删除了所有内容并重新开始,我遇到了同样的问题。我添加了一个断点,数组被填满。我还看到了其他解决方案,reloadData()在数组填充后使用但对我不起作用

主视图控制器:

//Variable declarations
var recentlyPlayed = [RecentlyPlayed]()
private var info = UserDefaults.standard.dictionary(forKey: "parseJSON")
var userLikedSongs = [LikedSongs]()
var refreshControl: UIRefreshControl!


@IBOutlet weak var LikedSongsCollectionView: UICollectionView!
@IBOutlet weak var RecentlyPlayedCollectionView: UICollectionView!
@IBOutlet weak var scrollView: UIScrollView!

//Once view has loaded
override func viewDidLoad() {
   super.viewDidLoad()
    
    //Assign Collection views to self
    RecentlyPlayedCollectionView.delegate = self
    RecentlyPlayedCollectionView.dataSource = self
    LikedSongsCollectionView.delegate = self
    LikedSongsCollectionView.dataSource = self
    
    // Get user id and users recently played songs
    let user = getId()
    let id = Int(user)!
    retriveRecentSongs(info: id)
    retriveLikedSongs(info: id)
    RecentlyPlayedCollectionView.reloadData()
    LikedSongsCollectionView.reloadData()

   //Hide navigation bar
   self.navigationController?.isNavigationBarHidden = true        
    
}

// Define Recent songs collection view count
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if(collectionView == RecentlyPlayedCollectionView) {
        return recentlyPlayed.count
    } else {
        return userLikedSongs.count
    }
}
//Set content inside recently collection view cells
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
    if (collectionView == LikedSongsCollectionView) {
        
        let likeCell = collectionView.dequeueReusableCell(withReuseIdentifier: "LikedCell", for: indexPath) as! LikedSongsCollectionViewCell
        
        likeCell.LikedData = userLikedSongs[indexPath.row]
        
        return likeCell
    } else {
        let recentCell = collectionView.dequeueReusableCell(withReuseIdentifier: "RecentlyPlayedCell", for: indexPath) as! RecentlyPlayedCollectionViewCell
    
        recentCell.Recentdata = recentlyPlayed[indexPath.row]
        
        return recentCell
    }
}
//Get users recenlty played song with URL session
func retriveRecentSongs(info: Int) {
    let url = URL(string: "http://127.0.0.1/musicfiles/getRecentlyPlayed.php?info=" + String(info))
    URLSession.shared.dataTask(with: url!) { data, response, error in
        let retrievedList = String(data: data!, encoding: String.Encoding.utf8)
        print(retrievedList!)
        self.parseRecentSongs(data: retrievedList!)
    }
    .resume()
    print("Getting songs")
}
func parseRecentSongs (data: String) {
    if (data.contains("*")) {
        let dataArray = (data as String).split(separator: "*").map(String.init)
        for item in dataArray {
            let itemData = item.split(separator: ",").map(String.init)
            let newSong = RecentlyPlayed(id: itemData[0], songName: itemData[1], trackName: itemData[2], artist: itemData[3], owner: itemData[4], cover: itemData[5])
            recentlyPlayed.append(newSong)
        }
        
    }
    
}

如果需要,还可以添加最近播放的CollectionViewCell 和 LikedSongsCollectionView。

标签: swiftuicollectionview

解决方案


您的函数retriveRecentSongs包含一个异步闭包。这意味着它内部的代码即使在被调用并返回后也会继续执行。

func retriveRecentSongs(info: Int) {
    let url = URL(string: "http://127.0.0.1/musicfiles/getRecentlyPlayed.php?info=" + String(info))

    /// See here!
    URLSession.shared.dataTask(with: url!) { data, response, error in
        let retrievedList = String(data: data!, encoding: String.Encoding.utf8)
        print(retrievedList!)
        self.parseRecentSongs(data: retrievedList!)
    }
    .resume()
    print("Getting songs")
}

您可能会注意到之前print("Getting songs")的打印方式。 print(retrievedList!)

打印“获取歌曲”时,您才刚刚开始URL任务,尚未完成下载。此时,依然recentlyPlayed的。

retriveRecentSongs(info: id) /// started the download
RecentlyPlayedCollectionView.reloadData() /// but at this point, has not completed yet.

reloadData下载完成后您需要致电。

func retriveRecentSongs(info: Int) {
    let url = URL(string: "http://127.0.0.1/musicfiles/getRecentlyPlayed.php?info=" + String(info))
    URLSession.shared.dataTask(with: url!) { data, response, error in
        let retrievedList = String(data: data!, encoding: String.Encoding.utf8)
        print(retrievedList!)

        /// ok, the download finished, parse the songs
        self.parseRecentSongs(data: retrievedList!)
    }
    .resume()
    print("Getting songs")
}
func parseRecentSongs (data: String) {
    if (data.contains("*")) {
        let dataArray = (data as String).split(separator: "*").map(String.init)
        for item in dataArray {
            let itemData = item.split(separator: ",").map(String.init)
            let newSong = RecentlyPlayed(id: itemData[0], songName: itemData[1], trackName: itemData[2], artist: itemData[3], owner: itemData[4], cover: itemData[5])
            recentlyPlayed.append(newSong)
        }
    }

    /// now, do reloadData.
    RecentlyPlayedCollectionView.reloadData()
}

还要确保你删除

RecentlyPlayedCollectionView.reloadData()
LikedSongsCollectionView.reloadData()

里面viewDidLoad()


推荐阅读