【问题标题】:Set a default image in TableViewCell在 TableViewCell 中设置默认图像
【发布时间】:2018-04-04 05:27:32
【问题描述】:

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

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)
            """)
    }

}

【问题讨论】:

  • 在从服务器下载图像之前,将placeholder image 放置到您的imageview。成功后将下载的图像设置为您的imageview,如果您没有从服务器获取任何图像,请将placeholder 保留为您的imageview
  • @iPeter 我该怎么做呢?我是新手。

标签: ios json swift xcode tableview


【解决方案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()
    }

    //...
}

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

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

【讨论】:

【解决方案2】:

在下载专辑图片的代码上方设置“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

}

【讨论】:

    【解决方案3】:
    guard let image = imageData else { cell.songCover.image = UIImage(named : "your_image_name"); return }
    

    【讨论】:

      【解决方案4】:

      请使用 Kingfisher 库,它将从 url 下载图像并设置占位符 image.Library URL:- https://github.com/onevcat/Kingfisher

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        相关资源
        最近更新 更多