How to update table view

时光总嘲笑我的痴心妄想 提交于 2019-12-24 09:18:14

问题


I used search bar. It isn't updating the table view.

struct ApiResults:Decodable {
    let resultCount: Int
    let results: [Music]
}

struct Music:Decodable {
    let trackName: String?
    let artistName: String?
    let artworkUrl60: String?
}

class ItunesDataViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableView: UITableView!
    var musicArray:[Music] = []
    var mArray:[Music] = []
    var filteredData:[Music] = []
    var isSearching = false

    override func viewDidLoad() {
        super.viewDidLoad()

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

        self.searchBar.delegate = self
        searchBar.placeholder = "search"

    }
     func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
    {

        print("\n\nsearchText : \(searchText)\n\n")
        Search(searchTerm: "\(searchText)")

        if searchBar.text == nil || searchBar.text == ""
        {
            isSearching = false
            view.endEditing(true)
            self.tableView.reloadData()
        }
        else
        {
            isSearching = true
            filteredData = mArray.filter{$0.artistName == searchText}
            self.tableView.reloadData()
        }

    }
    func Search(searchTerm: String)
    {

        guard let url = URL(string: "https://itunes.apple.com/search?term=\(searchTerm)&attribute=actorTerm&attribute=languageTerm&attribute=allArtistTerm&attribute=tvEpisodeTerm&attribute=shortFilmTerm&attribute=directorTerm&attribute=releaseYearTerm&attribute=titleTerm&attribute=featureFilmTerm&attribute=ratingIndex&attribute=keywordsTerm&attribute=descriptionTerm&attribute=authorTerm&attribute=genreIndex&attribute=mixTerm&attribute=allTrackTerm&attribute=artistTerm&attribute=composerTerm&attribute=tvSeasonTerm&attribute=producerTerm&attribute=ratingTerm&attribute=songTerm&attribute=movieArtistTerm&attribute=showTerm&attribute=movieTerm&attribute=albumTerm") else {return}
        URLSession.shared.dataTask(with: url){(data, response, error) in
            guard let data = data else {return}

            do
            {
                let apiressults = try JSONDecoder().decode(ApiResults.self, from: data)

                for item in apiressults.results
                {
                    if let track_Name = item.trackName, let artist_Name = item.artistName, let artwork_Url60 = item.artworkUrl60
                    {
                        let musics = Music(trackName: track_Name, artistName: artist_Name, artworkUrl60: artwork_Url60)
                        self.musicArray.append(musics)
                        print(musics.artistName!,"-", musics.trackName!)
                    }
                }                
                DispatchQueue.main.async
                    {
                        self.tableView.reloadData()
                }
            }
            catch let jsonError
            {
                print("Error:", jsonError)
            }
            }.resume()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if isSearching
        {
            return filteredData.count
        }
        else
        {
            return mArray.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "musicCell", for: indexPath) as! ItunesDataTableViewCell

        if isSearching
        {
            cell.lblDesc?.text = filteredData[indexPath.row].artistName
            cell.lblSongDesc?.text = filteredData[indexPath.row].trackName
            let imgString = filteredData[indexPath.row].artworkUrl60!

            let imgUrl:URL = URL(string: imgString)!
            DispatchQueue.global(qos: .userInitiated).async {

                let imageData:NSData = NSData(contentsOf: imgUrl)!

                DispatchQueue.main.async {
                    let image = UIImage(data: imageData as Data)
                    cell.imgArt?.image = image
                }
            }
        }
        else
        {
            cell.lblDesc?.text = mArray[indexPath.row].artistName
            cell.lblSongDesc?.text = mArray[indexPath.row].trackName
            let imgString = mArray[indexPath.row].artworkUrl60!

            let imgUrl:URL = URL(string: imgString)!
            DispatchQueue.global(qos: .userInitiated).async {

                let imageData:NSData = NSData(contentsOf: imgUrl)!

                DispatchQueue.main.async {
                    let image = UIImage(data: imageData as Data)
                    cell.imgArt?.image = image
                }
            }
        }

        return cell
    }
}

回答1:


Please clean up your code 😉: You have two different arrays mArray and musicArray.

You are populating musicArray in Search but mArray is used as data source.

Why do you create new Music items from Music items? You can reduce the code to

let apiressults = try JSONDecoder().decode(ApiResults.self, from: data)
self.mArray = apiressults.results
DispatchQueue.main.async {
   self.tableView.reloadData()
}



回答2:


Please change your code in the cellForRowAt delegate method to:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "musicCell", for: indexPath) as! ItunesDataTableViewCell

        let tempArray: [Music] = isSearching ? filteredData : musicArray

        cell.lblDesc?.text = tempArray[indexPath.row].artistName
        cell.lblSongDesc?.text = tempArray[indexPath.row].trackName

        guard let imgString = tempArray[indexPath.row].artworkUrl60,
            let imgUrl = URL(string: imgString) else {
                // Handle properly the fact that there's no image to display
                return cell
        }

        // Review this code as I'm not sure about this double dispatch
        // However, please, no force unwrap optionals (!)
        DispatchQueue.global(qos: .userInitiated).async {
            do {
                let imageData = try Data(contentsOf: imgUrl)
                DispatchQueue.main.async {
                    let image = UIImage(data: imageData)
                    cell.imgArt?.image = image
                }
            } catch let error {
                print("Error with the image URL: ", error)
            }
        }
        return cell
    }

See how you don't repeat your code that way?

Furthermore you were not using the right music array, or we don't have all the information to assess what is wrong with this mix of mArray and musicArray.



来源:https://stackoverflow.com/questions/52935997/how-to-update-table-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!