在全局线程中调整大小后,无法在uicollectionview中加载图像

时间:2017-08-17 08:08:52

标签: swift xcode multithreading uicollectionview

在调整大小后,我一直在尝试在uicollectionview中加载图像。如何在后台线程上调整图像大小,然后在uicollectionview中加载。我尝试了下面的代码,但是图片没有加载到集合视图中。

调整大小的功能

func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
    let size = image.size

    let widthRatio  = targetSize.width  / image.size.width
    let heightRatio = targetSize.height / image.size.height

    // Figure out what our orientation is, and use that to form the rectangle
    var newSize: CGSize
    if(widthRatio > heightRatio) {
        newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
    } else {
        newSize = CGSize(width: size.width * widthRatio,  height: size.height * widthRatio)
    }

    // This is the rect that we've calculated out and this is what is actually used below
    let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)

    // Actually do the resizing to the rect using the ImageContext stuff

    var newImage = UIImage()
    DispatchQueue.global().async {
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        image.draw(in: rect)
        newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
    }


    return newImage
}

这是在cellForItemAt函数中:

if let imageView = cell.viewWithTag(499) as? UIImageView {
        let image = self.cardImages[indexPath.item]
        imageView.image = resizeImage(image: image, targetSize: CGSize(width: 100, height: 100))

    }

1 个答案:

答案 0 :(得分:0)

在调整大小图像方法中,您正在使用线程。因此,您需要在队列括号内使用completionHandler块。在您的代码中,当全局队列调用异步时,您将返回一个空图像。如果您需要代码示例,请告诉我,我将编辑我的答案

====== EDIT ==============

func resizeImage(image: UIImage, targetSize: CGSize, completionHandler: @escaping (_ image: UIImage?) -> ()) {
    let size = image.size

    let widthRatio  = targetSize.width  / image.size.width
    let heightRatio = targetSize.height / image.size.height

    // Figure out what our orientation is, and use that to form the rectangle
    var newSize: CGSize
    if(widthRatio > heightRatio) {
        newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
    } else {
        newSize = CGSize(width: size.width * widthRatio,  height: size.height * widthRatio)
    }

    // This is the rect that we've calculated out and this is what is actually used below
    let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)

    // Actually do the resizing to the rect using the ImageContext stuff

    var newImage = UIImage()
    DispatchQueue.global().async {
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        image.draw(in: rect)
        newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        //now we need to return to the main thread
        //NOTE! This is Swift 3 code
        DispatchQueue.main.async {
             //return the image
             completionHandler(newImage)
        }
    }
}

现在,您想要获取图像的方法:

if let imageView = cell.viewWithTag(499) as? UIImageView {
        let image = self.cardImages[indexPath.item]

        resizeImage(image: image, targetSize: CGSize(width: 100, height: 100)) { image in
            imageView.image = image
        }
}

顺便说一句,我不会在cellForRow方法中使用这个方法,我更喜欢在Custom cell类中设置它。但取决于你。