在TableViewCell中设置默认图像

时间:2018-04-04 05:27:33

标签: ios json swift xcode tableview

我尝试了几种不同的方法,但还没有任何方法可行。我正在为我的广播电台应用程序提供最近播放的tableview的专辑插图。当没有专辑插图进入单元格时,我会得到空白图像。我只想将我的电台标志“WhiteLogo.png”作为占位符,只要没有专辑插图进入tableview单元格。非常感谢任何正确方向的帮助。感谢

import UIKit

//----------
//MARK: JSON
//----------

//The Initial Response From The JSON
struct Response: Codable {

    var playHistory: Album

}

//The Album Received Which Is An Array Of Song Data
struct Album: Codable {
    var song: [SongData]

}

//The SongData From The PlayHistory Album
struct SongData: Codable{

    var album: String
    var artist: String
    var cover: String
    var duration: String
    var programStartTS: String
    var title: String
}


class TableViewController: UITableViewController {

    //1. Create An Array To Store The SongData
    var songs = [SongData]()
    var currentStation: RadioStation!
    var downloadTask: URLSessionDownloadTask?

    override func viewDidLoad() { super.viewDidLoad()


        self.tableView.delegate = self
        self.tableView.dataSource = self

        //2. Load The JSON From The Main Bundle

        guard let urlText = URL (string: "http://streamdb3web.securenetsystems.net/player_status_update/JACKSON1_history.txt")
            else { return }


        do{
            //a. Get The Data From The From The File
            let data = try Data(contentsOf: urlText)

            //b. Decode The Data To Our Structs
            let albumData = try JSONDecoder().decode(Response.self, from: data)

            //c. Append The Songs Array With The PlayHistory
            albumData.playHistory.song.forEach { songs.append($0) }

            //d. Test Some Data
            print("""
                **The First Album Details**
                Album = \(songs[0].album)
                Artist = \(songs[0].artist)
                Cover = \(songs[0].cover)
                Duration = \(songs[0].duration)
                Start = \(songs[0].programStartTS)
                Title = \(songs[0].title)
                """)

            //3. Load The Data
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }catch{

            print(error)
        }

    }

    //-----------------
    //MARK: UITableView
    //-----------------


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return songs.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        //1. Create A Cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell

        //2. Set It's Text
        cell.songTitle.text = songs[indexPath.row].title
        cell.artistLabel.text = songs[indexPath.row].artist

        //3. Get The Image
        if let imageURL = URL(string: songs[indexPath.row].cover){

            let request = URLSession.shared.dataTask(with: imageURL) { (imageData, response, error) in

                if let error = error{

                    print(error)

                }else{

                    guard let image = imageData else { return }

                    DispatchQueue.main.async {
                        cell.songCover.image = UIImage(data: image)
                        cell.setNeedsLayout()
                        cell.layoutIfNeeded()
                    }

                }
            }


            request.resume()
        }

        return cell

    }


    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        print("""
            **Album \(indexPath.row) Selected**
            Album = \(songs[indexPath.row].album)
            Artist = \(songs[indexPath.row].artist)
            Cover = \(songs[indexPath.row].cover)
            Duration = \(songs[indexPath.row].duration)
            Start = \(songs[indexPath.row].programStartTS)
            Title = \(songs[indexPath.row].title)
            """)
    }

}

4 个答案:

答案 0 :(得分:1)

需要正确处理案件 我首先设置占位符图像,然后继续从URL下载图像。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //...

    /*
     Start with placeholder image so it shows until the image  download completes.
     And if the next `if let imageURL` condition fails, the placeholder image will stay
     */
    cell.songCover.image = UIImage(named: "WhiteLogo")

    //Continue with your logic, no change really but could be shortened to:
    if let imageURL = URL(string: songs[indexPath.row].cover) {
        let request = URLSession.shared.dataTask(with: imageURL) { (imageData, response, error) in
            guard let imageData = imageData else { return }

            DispatchQueue.main.async {
                cell.songCover.image = UIImage(data: imageData)
            }
        }

        request.resume()
    }

    //...
}

但是,由于图像下载逻辑是异步的,如果在下载完成之前重复使用该单元,则会出现异常。
即第一首歌的图像下载开始,但你滚动得足够快,重新使用第一个单元格,比如第三首歌曲 现在,当下载完成时,第一个图像可以显示在第三个单元格上。

如果你遇到这个问题,请告诉我,我会更新我的答案。

答案 1 :(得分:0)

在代码上方设置“WhiteLogo.png”,如果相册图像数据为guard let image = imageData else { var image : UIImage = UIImage(named:"WhiteLogo.png")!

,则下载相册图像或设置徽标图像
cell.songCover.image = UIImageView(image: image) }

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


    //1. Create A Cell
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell

    //2. Set It's Text
    cell.songTitle.text = songs[indexPath.row].title
    cell.artistLabel.text = songs[indexPath.row].artist

   //set image
    var image : UIImage = UIImage(named:"WhiteLogo.png")!
    cell.songCover.image = UIImageView(image: image)

    //3. Get The Image
    if let imageURL = URL(string: songs[indexPath.row].cover){

        let request = URLSession.shared.dataTask(with: imageURL) { (imageData, response, error) in

            if let error = error{

                print(error)

            }else{

                guard let image = imageData else { return }

                DispatchQueue.main.async {
                    cell.songCover.image = UIImage(data: image)
                    cell.setNeedsLayout()
                    cell.layoutIfNeeded()
                }

            }
        }


        request.resume()
    }

    return cell

}

答案 2 :(得分:0)

guard let image = imageData else { cell.songCover.image = UIImage(named : "your_image_name"); return }

答案 3 :(得分:0)

请使用Kingfisher图书馆,它会从网址下载图片并设置占位符图片。图书馆网址: - https://github.com/onevcat/Kingfisher

相关问题