iOS UIImageView未自动刷新



我正在按照这个精彩的教程学习iOS编程,只是我的目标是iOS 9并进行了一些小的修改。

在下面的tableView()函数中,我可以下载缩略图并调用我的处理程序,这从控制台打印出的两条日志行中可以明显看出。然而,当应用程序(在模拟器中)运行时,我必须单击每个表单元格才能显示图像。我试图查看UIImageView或表单元格中是否有refresh()或类似的内容,但一无所获。

如何在收到数据后立即显示图像?

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier)!
    let album = self.albums[indexPath.row]
    // ... setting up other cell's data, see the tutorial link
    // Start by setting the cell's image to a static file
    // Without this, we will end up without an image view!
    cell.imageView?.image = UIImage(named: "Blank52")
    let request: NSURLRequest = NSURLRequest(URL: thumbnailURL)
    let urlSession = NSURLSession.sharedSession()
    urlSession.dataTaskWithRequest(request, completionHandler: {(data, response, error) -> Void in
        print("received thumbnail (thumbnailURLString)") // reached
        if error == nil {
            // Convert the downloaded data in to a UIImage object
            let image = UIImage(data: data!)
            // Update the cell
            dispatch_async(dispatch_get_main_queue(), {
                print("...dispatched thumbnail image for (thumbnailURLString)") // reached
                if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
                    cellToUpdate.imageView?.image = image
                }
            })
        }
    }).resume()
    return cell
}

这个部分没有意义:

if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
    cellToUpdate.imageView?.image = image

这似乎在创造一个无限循环。对cellForRowAtIndexPath的每次调用都会导致对cellForRowAtIndexPath的另一次调用。

我想你的意思是:

cell.imageView?.image = image

你已经知道这个牢房了。您在调用此块之前刚刚创建了它。你不需要再查了。

我想出了一个变通办法。如果我也稍微更新了一下文本,那么图像就会直接显示出来,而不会单击表视图单元格。

cellToUpdate.imageView?.image = image
cellToUpdate.textLabel?.text = "(album.title) " // a space is added to the end to make a difference and force the cell to be updated

对我来说,这听起来像是UITableViewCell中的一个错误(或者模拟器?还没有在真正的设备上尝试过)。

为什么你只是在没有dispatch_async(dispatch_get_main_queue())部分的情况下尝试。

dispatch_async(dispatch_get_main_queue(), {
            print("...dispatched thumbnail image for (thumbnailURLString)") // reached
            if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
                cellToUpdate.imageView?.image = image
            }
        })

cell.imageView?.image = image

获取要更新的单元格时,可能需要强制转换单元格。

dispatch_async(dispatch_get_main_queue(), {
        print("...dispatched thumbnail image for (thumbnailURLString)") // reached
        if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) as! UITableViewCell {
            cellToUpdate.imageView?.image = image
    }
})

Swift 5设置图像后,只需将以下代码放入cellForRowAt委托方法中。

        UIView.performWithoutAnimation {
           tableView.beginUpdates()
           tableView.endUpdates()
        }
    // Full Method
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                guard let cell = tableView.dequeueReusableCell(withIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UITableViewCell() }
                let model = self.arrPhotos?[indexPath.row]
// Below method download image from url using asycn
                SwiftHelper.downloadImageFrom(strUrl: model?.url ?? "") {[weak self] (img) in
                    guard let _ = self, let image = img else { return }
                    print("ImgDownloaded")
                    cell.imgView.image = image
                   // cell.layoutIfNeeded()
                    UIView.performWithoutAnimation {
                       tableView.beginUpdates()
                       tableView.endUpdates()
                    }
                }
                return cell
            }

若要对图像执行动画,可以移除performWithoutAnimation块。

最新更新