在 TableViewCell 中设置默认图像

Posted

技术标签:

【中文标题】在 TableViewCell 中设置默认图像【英文标题】:Set a default image in 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)
            """)
    


【问题讨论】:

见***.com/questions/46199203/… 在从服务器下载图像之前,将placeholder image 放置到您的imageview。成功后将下载的图像设置为您的imageview,如果您没有从服务器获取任何图像,请将placeholder 保留为您的imageview @iPeter 我该怎么做呢?我是新手。 【参考方案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()
    

    //...

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

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

【讨论】:

嘿先生您能帮我解决这个问题吗? ***.com/questions/49639673/…【参考方案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

【讨论】:

以上是关于在 TableViewCell 中设置默认图像的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ios 中使用图案图像在可扩展的 tableViewCell 中设置 UIButton

如何在 TableViewCell 中设置图标的背景颜色?

如何在 TableView Cell 中设置随机图像

解析和斯威夫特。从 Parse 关系中设置 tableViewCell 附件类型

TableViewCell 颜色问题

无法在 tableView:cellForRowAtIndexPath: 方法中设置标签框