简体   繁体   中英

UITableViewCell, images and aspect ratio

I have a UITableView and I need to show different images (with different sizes) in each custom cell (with UIImageView). In order to display them properly I need to calculate aspect ratio of each image and adjust UIImageView's frame. But there is a problem. When I run the app, it displays wrong aspect ratio for every cell. Then I start sliding to the bottom of the table, and back to the top again, several times. And each time I see right aspect ratio, for some cells, and wrong for others. Is it because the system is reusing the prototype cell?

Here is the code in tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) :

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("EntryCell", forIndexPath: indexPath) as? PodCell

    let podcast = podList[indexPath.row]
    let title = podcast.title
    //        cell.titleLa?.text = title
    cell?.titleLabel.lineBreakMode = .ByWordWrapping
    cell?.titleLabel.numberOfLines = 0
    cell?.titleLabel.text = title
    var image = UIImage()
    if (imageCache[podcast.imageURL!] != nil) {
        image = imageCache[podcast.imageURL!]!
        cell?.imgView.image = image
    }else{
        let imgURL = NSURL(string: podcast.imageURL!)
        let request = NSURLRequest(URL: imgURL!)

        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: config)
        let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?,  error:NSError?) in
            if error == nil {
                if data != nil {
                    image = UIImage(data: data!)!
                }

                dispatch_async(dispatch_get_main_queue(), {
                    self.imageCache[podcast.imageURL!] = image
                    cell?.imgView.image = image
                })

            }else {
                print(error)
            }
        }

        task.resume()
    }
    let aspectRatio = image.size.width / image.size.height

    cell?.imgView.frame = CGRectMake((cell?.imgView.frame.origin.x)!, (cell?.imgView.frame.origin.y)!, (cell?.imgView.frame.width)!, (cell?.imgView.frame.width)! / aspectRatio)

    return cell!
}

You can't use the imageView's frame's width as a basis for the new width. You need to use a constant value for that, maybe the height.

Yup cells are reused, it would be nice to post whole code from this method, especaily part where you create cell.

From what I gather from this, is you try to load image from cache, and if it's not there you load it from internet. Problem with this solution is when you don't have image, you present some stub image with aspect ratio of stub. When real image is finished with loading, it will just be placed inside UIImageView , without resizing.

There are 2 ways to do this. One is to have constant image size. The other is to reload cell when loading of new image has finished.

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