简体   繁体   中英

About return CGFloat value in Swift 4

After I download the image, I created a function that returns the vertical value of the image.

However, the vertical value of the image will fail with a CGFloat value return.

This source code is to download and return.

extension HomeViewController : PinterestLayoutDelegate
{
    func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath:IndexPath) -> CGFloat
    {
        let arts = self.artList

        let model = arts![indexPath.row]

        let urlString = model.url!
        let urll = NSURL(string: urlString)

        return downloadImage(from: urll! as URL)
    }
}

extension HomeViewController
{
    func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ())
    {
        URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
    }

    func downloadImage(from url: URL) -> CGFloat
    {
        getData(from: url)
        { data, response, error in
        guard let data = data, error == nil else { return }
            {
                let image = UIImage(data: data)
                let heightInPoints = image!.size.height
                return heightInPoints
            }
        }
    }
}

But I am getting an error at

return heightInPoints

Error states

Unexpected non-void return value in void function

Please help me.

The problem is that you want to return a value inside a completion block , you need

func downloadImage(from url: URL,completion(_ value:CGFloat) -> Void )
{
    getData(from: url)
    { data, response, error in
    guard let data = data, error == nil else { return }
        {
            let image = UIImage(data: data)
            let heightInPoints = image!.size.height
            completion(heightInPoints)
        }
    }
}

BTW you can't do this

return downloadImage(from: urll! as URL)

inside heightForPhotoAtIndexPath as downloadImage is asynchronous method that it's response depends on network status not serially in code , it's call would look like

// array of heights
var arr = [CGFloat]()
let urll = URL(string: urlString)
downloadImage(from: urll!) { (value) in 
  print(value)
  // append the value to it's corresponding index in an array of floats
  DispatchQueue.main.async {
    self.collectionview.reloadData()
  }
}

you need to have a predefined list of heights for the images if possible , if not then grab all the heights then refresh the collection

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