【问题标题】:how to load an image in async way on an object in Swift如何在Swift中的对象上以异步方式加载图像
【发布时间】:2017-08-16 14:44:41
【问题描述】:

我采用了一个 iOS 项目,需要为对象添加图像方法。我在想这样的事情。但是,我将如何声明 image 方法以返回 UIImage?或者这甚至可能吗?

从更大的角度来看,这些项目将位于 UICollection 视图中,因此我需要加载图像以确定自定义 UICollectionViewCell 的高度。

class Item {
  var imageURL = "https://s3-us-west-1.amazonaws.com/bucket/images/26882/abc.jpg?1477323919"

  // probably need to change this
  func image() -> UIImage {
    URLSession.shared.dataTask(with: NSURL(string: imageURL)! as URL, completionHandler: { (data, response, error) -> Void in

      if error != nil {
        print(error)
        return
      }
      DispatchQueue.main.async(execute: { () -> Void in
        let image = UIImage(data: data!)
        return image
      })

    }).resume()
  }}
  }

编辑#1

这是此调用的使用者 - 不确定我是否可以调整它以使其适合异步调用以获取图像。在 JSON 调用中向下发送元数据可能比通过此异步调用计算它更容易。

extension MasterViewController: MosaicLayoutDelegate {
  func collectionView(_ collectionView: UICollectionView, heightForImageAtIndexPath indexPath: IndexPath, withWidth width: CGFloat) -> CGFloat {
    let item = items[indexPath.item]
    let image = item.image() // need to get this height


    let boundingRect = CGRect(x: 0, y: 0, width: width, height: CGFloat(MAXFLOAT))
    let rect = AVMakeRect(aspectRatio: image.size, insideRect: boundingRect)
    return rect.height
  }

【问题讨论】:

    标签: ios asynchronous


    【解决方案1】:

    由于它是异步的,因此您的方法需要接受一个完成块,该块将在图像下载后被调用。比如:

    func image(completionBlock: @escaping ((UIImage) -> Void)) {
        URLSession.shared.dataTask(with: NSURL(string: imageURL)! as URL, completionHandler: { (data, response, error) -> Void in
    
            if error != nil {
                print(error)
                return
            }
    
            let image = UIImage(data: data!)
            completionBlock(image!)
        }).resume()
    }
    

    Explanation for the @escaping attribute.

    然后要使用此方法并显示图像,您将执行以下操作(假设 self.imageView 是您要显示图像的位置):

    func displayImage() {
        self.image { (retrievedImage) in
            DispatchQueue.main.async {
                self.imageView.image = retrievedImage
            }
        }
    }
    

    【讨论】:

    • thx - 不幸的是,我不只是将它放入 UIImageView - 我需要下载它以获得集合视图来计算大小。我已经包含了上面的代码,但不确定如何实现这一点(如果可能的话)——是否可以针对这种类型的调用进行调整。我正在考虑用它发送元信息,而不是在应用程序中计算。
    • 对于在 collectionView 中使用,更简单的解决方案是预先下载所有图像,以便您可以将其同步交给 collectionView,或者调整所有图像的大小以适应预定义的大小。
    • 一个有点复杂/花哨的解决方案是显示一个固定的加载图像并开始下载图像。下载图像后,您可以将单元格调整大小(甚至动画调整大小)到图像尺寸。见stackoverflow.com/questions/13780153/…
    猜你喜欢
    • 1970-01-01
    • 2019-12-30
    • 2018-03-23
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    相关资源
    最近更新 更多