简体   繁体   中英

Async load image to custom UITableViewCell partially working

My images dont load into the imageview until you scroll the cell off the table and back on, or go to another view and come back to the the view (redraws the cell).

How do I make them load in correctly?

/////////

My viewDidLoad has this in it:

    tableView.delegate = self
    tableView.dataSource = self

    DispatchQueue.global(qos: .background).async {
        self.getBusinesses()

        DispatchQueue.main.async {

            self.tableView.reloadData()


        }
    }

I call the function download the image here in the .getBusinesses function called in viewDidLoad:

func getBusinesses() -> Array<Business> {

    var businessList = Array<Business>()
    //let id  = 1
    let url = URL(string: "**example**")!
    let data = try? Data(contentsOf: url as URL)
    var isnil = false

    if data == nil{
        isnil = true
    }
    print("is nill is \(isnil)")


    if(data == nil){
        print("network error")
        businessList = []
        return businessList
    }
    else{
        values = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
    }

    let json = JSON(values)

    var i = 0;
    for (key, values) in json {

        var businessReceived = json[key]
        let newBusiness = Business(id: "18", forename: "", surname: "", email: "", password: "", business: true, level: 1, messageGroups: [], problems: [])

        newBusiness.name = businessReceived["name"].stringValue
        newBusiness.description = businessReceived["description"].stringValue
        newBusiness.rating = Int(businessReceived["rating"].doubleValue)
        newBusiness.category = businessReceived["category"].intValue
        newBusiness.distance =  Double(arc4random_uniform(198) + 1)
        newBusiness.image_url  = businessReceived["image"].stringValue
        newBusiness.url  = businessReceived["url"].stringValue
        newBusiness.phone  = businessReceived["phone"].stringValue
        newBusiness.postcode  = businessReceived["postcode"].stringValue
        newBusiness.email = businessReceived["email"].stringValue
        newBusiness.id = businessReceived["user_id"].stringValue

        if(newBusiness.image_url  == ""){
            newBusiness.getImage()

        }
        else{
            newBusiness.image = #imageLiteral(resourceName: "NoImage")
        }


        if(businessReceived["report"].intValue !=  1){
            businessList.append(newBusiness)

        }
    }

    businesses = businessList

    print(businesses.count)
    holdBusinesses = businessList
    return businessList

}

Here in the business object i have this method to download the image from the url and store it in the business object's image property:

 func getImage(){

    if(self.image_url != ""){

        print("runs imageeee")
        var storage = FIRStorage.storage()

        // This is equivalent to creating the full reference
        let storagePath = "http://firebasestorage.googleapis.com\(self.image_url)"
        var storageRef = storage.reference(forURL: storagePath)




        // Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
        storageRef.data(withMaxSize: 30 * 1024 * 1024) { data, error in
            if let error = error {
                // Uh-oh, an error occurred!
            } else {
                // Data for "images/island.jpg" is returned
                self.image = UIImage(data: data!)!
                print("returned image")
            }
        }


    }
    else{

        self.image = #imageLiteral(resourceName: "NoImage")

    }

}

I then output it in the tableview here:

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

    let cell  = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for : indexPath) as! BusinessesViewCell


            cell.businessImage.image = businesses[(indexPath as NSIndexPath).row].image


            //.............  

     return cell
}
            self.image = UIImage(data: data!)!

should become

    DispatchQueue.main.async {
         self.image = UIImage(data: data!)!
    }

Inside

    storageRef.data(withMaxSize: 30 * 1024 * 1024) { data, error in

EDIT: My initial thought was the download logic was inside the cell, now I know its not.

you either need to call reloadData() on the tableView each time you get to

         self.image = UIImage(data: data!)!

or better yet find out which index you just updated, then called

  tableView.reloadRows:[IndexPath]

您可以使用

cell.businessImage.setNeedsLayout()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM