【问题标题】:Height UIImage asynchronously in UITableview with autolayout高度 UIImage 在具有自动布局的 UITableview 中异步
【发布时间】:2018-04-06 18:21:32
【问题描述】:

我在 UITableView 中显示图像,图像将具有不同的大小,并通过 JSON 下载,以下代码显示图像正确缩放,但上下有一些大空间(绿色)。我怎样才能消除这些空格?

图像的上下左右约束为 0,以便能够使用自动布局

import UIKit

class ViewController: UIViewController, UITableViewDataSource {

    struct JsonSosTalleres : Codable {
        let titulo : String
        let image : String
    }

    private var datosOfertas = [JsonSosTalleres]()

    class ImageLoader {

        var cache = NSCache<AnyObject, AnyObject>()

        class var sharedInstance : ImageLoader {
            struct Static {
                static let instance : ImageLoader = ImageLoader()
            }
            return Static.instance
        }

        func imageForUrl(urlString: String, completionHandler:@escaping (_ image: UIImage?, _ url: String) -> ()) {
            let data: NSData? = self.cache.object(forKey: urlString as AnyObject) as? NSData

            if let imageData = data {
                let image = UIImage(data: imageData as Data)
                DispatchQueue.main.async {
                    completionHandler(image, urlString)
                }
                return
            }

            let downloadTask: URLSessionDataTask = URLSession.shared.dataTask(with: URL.init(string: urlString)!) { (data, response, error) in
                if error == nil {
                    if data != nil {
                        let image = UIImage.init(data: data!)
                        self.cache.setObject(data! as AnyObject, forKey: urlString as AnyObject)
                        DispatchQueue.main.async {
                            completionHandler(image, urlString)
                        }
                    }
                } else {
                    completionHandler(nil, urlString)
                }
            }
            downloadTask.resume()
        }
    }



    @IBOutlet weak var tabla: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()

        downloadJson()


        tabla.estimatedRowHeight = 40.0

        tabla.rowHeight = UITableViewAutomaticDimension

        tabla.tableFooterView = UIView()

    }








    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return datosOfertas.count
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tabla.dequeueReusableCell(withIdentifier: "ofertacell") as? TableViewCell else { return UITableViewCell() }


        let fimage = datosOfertas[indexPath.row].image
        ImageLoader.sharedInstance.imageForUrl(urlString: fimage, completionHandler: { (image, url) in
            if image != nil {


               tableView.beginUpdates()

                cell.imagen.image = image

                tableView.endUpdates()


            }
        })



        return cell
    }




    // download  json
    let url = URL(string: "http://sostalleres.com/test.json")

    func downloadJson() {
        guard let downloadURL = url else { return }
        URLSession.shared.dataTask(with: downloadURL) { data, urlResponse, error in
            guard let data = data, error == nil, urlResponse != nil else {
                print("something is wrong")
                return
            }
            print("downloaded")
            do
            {
                let decoder = JSONDecoder()
                self.datosOfertas = [try decoder.decode(JsonSosTalleres.self, from: data)]

                DispatchQueue.main.async {

                            self.tabla.reloadData()

                }

            } catch {
                print("something wrong after downloaded")
            }
            }.resume()
    }





}

在 TableViewCell.swift 中:

class TableViewCell: UITableViewCell {

    @IBOutlet weak var imagen: UIImageView!



    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

View image

如果您能指导我解决任何问题,我将不胜感激。

【问题讨论】:

  • 如果你的单元格中的imageView有"将上下左右约束为0",并且你正在使用它来确定单元格的高度(@987654325 @),它还需要高度和宽度约束。你有什么设置?
  • 感谢您的评论。如果我将高度放在图像上,它会像这样显示我:i.stack.imgur.com/hoNjV.png(因为我正在查看高度是动态的,它不应该有高度或宽度)
  • 好吧,你将以某种方式设置高度。通常,当您的代码下载图像时,您会获得下载图像的宽度/高度并根据需要调整图像视图的框架(在自动布局的情况下,您将保留 @IBOutlet 对宽度的引用或高度限制(或两者))。

标签: swift uitableview autolayout


【解决方案1】:

您必须计算新的高度和宽度,并使用它们应用比例并使用tableView.beginUpdates()tableView.endUpdates(),使用以下代码应该可以正常工作。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tabla.dequeueReusableCell(withIdentifier: "ofertacell") as? TableViewCell else { return UITableViewCell() }


        let fimage = datosOfertas[indexPath.row].image
        ImageLoader.sharedInstance.imageForUrl(urlString: encoded!, completionHandler: { (image, url) in
            if image != nil {


                let newWidth = self.self.imagenDetalle.frame.width
                let scale = newWidth/(image?.size.width)!
                let newHeight = (image?.size.height)! * scale



                        tableView.beginUpdates()

                        UIGraphicsBeginImageContext(CGSize(width:newWidth, height:newHeight))
                        image?.draw(in: CGRect(x:0, y:0, width:newWidth, height:newHeight))
                        let newImage = UIGraphicsGetImageFromCurrentImageContext()
                        UIGraphicsEndImageContext()
                        cell.imagen.image = newImage

                        tableView.endUpdates()


            }
        })



        return cell
    }

编码愉快!

【讨论】:

    【解决方案2】:

    我建议设置高度和宽度限制并创建相应的插座:

    @IBOutlet private weak var heightConstraint: NSLayoutConstraint!
    @IBOutlet private weak var widthConstraint: NSLayoutConstraint!
    

    您可以在同一个单元格上创建一个图像属性,该属性使用大小来设置图像视图大小和图像:

    internal var image: UIImage? {
        willSet {
            imageView.image = newValue
            guard let image = newValue else { return }
            heightConstraint.constant = image.size.height
            widthConstraint.constant = image.size.width
        }
    }
    

    这(可能是错误的)假设每个图像都是完美的尺寸。如果不是这种情况,您将需要自己进行一些缩放。

    【讨论】:

      猜你喜欢
      • 2014-07-06
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      相关资源
      最近更新 更多