ios – UIImageView最初不会在UITableViewCell中显示图像

我有一个UITableView从服务加载图像.它获取URL并使用NSURLSession.sharedSession()下载图像dataTaskWithURL:
NSURLSession.sharedSession().dataTaskWithURL(url,completionHandler: { (data,_,error) -> Void in
                            guard
                                let data = data where error == nil,let image = UIImage(data: data)
                                else {
                                    print(error?.localizedDescription)
                                    return
                            }
                            dispatch_async(dispatch_get_main_queue()) {
                                [unowned self] in
                                self.pictureView.image = image
                                self.pictureView.layoutIfNeeded()
                            }
                        }).resume()

UIImageView是故事板场景的出路. UIImageView内容模式是Aspect Fit.

即使我已经确认设置了一个图像,UIImageView的可见单元格最初显示为空(无图像).直到单元格滚动/屏幕上,单元格将重画(?)并显示图像.

所以这似乎是一些时间问题,但是我无法想像出来.设置图像后,我已经尝试在dispatch_async块中调用以下所有内容:

self.pictureView.setNeedsDisplay()
self.pictureView.setNeedsUpdateConstraints()
self.pictureView.setNeedsLayout()
self.pictureView.reloadInputViews()

这些都没有解决问题.导致此图像仅在单元格滚出/进入视图后才显示?

编辑:
可能重要的是要注意,这是在一个笔尖和相关的类中进行的.笔尖加载,然后我开始下载.我想知道笔尖是否放在自己的位置,当我的图像下载并设置在UIImageView上时,布局传递已经完成.然后通过移动单元格(包含笔尖)关闭/屏幕上,单元格再次执行布局,并且所有内容都正确显示.只是一个猜测,我仍然坚持这个.

编辑2:
进一步澄清过程:

1)我的UIViewController包含一个UITableView.

2)这个UITableView从一个称为PostCell的自定义UITableViewCell类加载单元.

3)PostCell的全部内容是从名为PostView的nib(使用PostView类)加载的单个视图.在init期间会发生这种负载:PostCell中的style:reuseIdentifier:

postView = NSBundle.mainBundle().loadNibNamed("PostView",owner: self,options: nil).first as? PostView

4)然后在PostView上设置一个Post对象:

postView.post = Post

请注意,在PostView上调用awakeFromNib()之后,会发生这种情况.

5)PostView上的post属性有一个didSet观察者,它基于post对象(上面的代码)中的URL来启动图像下载.图像被下载并设置在名为pictureView的UIImageView上.

编辑3:

这是tableView(_:cellForRowAtIndexPath :)的代码:

func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell = tableView.dequeueReusableCellWithIdentifier(postCellIdentifier) as? PostCell

        if cell == nil {
           cell = PostCell()
        }

        if let postCell = cell,let postArray = postArray,let post = postArray[indexPath.row] {
            postCell.post = post
            return postCell
        }

        // This section is hit during a refresh.
        let emptyCell = UITableViewCell()
        emptyCell.contentView.backgroundColor = .whiteColor()
        return emptyCell

    }

编辑4:

我发现如果我通过在笔尖中预设一个占位符图像来“优化”UIImageView,然后将我的图像加载到该UIImageView中,图像将显示在占位符的高度.当我将该单元格拉离屏幕然后再次打开时,UIImageView将使用笔尖中的约束设置以正确的大小绘制图像.

所以似乎UIImageView的约束和大小已经在图像加载时被设置,并且在屏幕上拉出它会导致重新调整图像的大小.如果我可以通过编程方式触发重绘,这将有所帮助,但是看到上面我已经尝试了.

编辑6:

这里是在行动.请注意,我已经在笔尖中设置了一个占位符图像.这似乎导致图像在最初加载时显示,但在占位符的维度上.当屏幕正确显示时,将其轻松地滚动使其重新调整大小.

编辑7

我的应用程序其他地方使用PostView nib没有问题.加载图像的大小正确.这个问题似乎表现在自己的嵌套在UITableViewCell中的笔尖.

编辑8:

我发现这个问题的根本原因,在我的UIViewController的viewDidLoad中调用:

tableView.estimatedRowHeight = 500
tableView.rowHeight = UITableViewAutomaticDimension

使用自动尺寸会导致初始不正确的行高.由于某些原因,将单元格向外滚动到视图中会重新计算行高度,并且图像将以正确的高度显示.删除此代码将显示图像,但行高不会受益于自动高度计算.自动计算行高的最佳方法是什么,还是避免这个问题?

解决方法

您可以尝试此扩展程序:
extension UIImageView {
    func downloadedFrom(link link:String,contentMode mode: UIViewContentMode) {
        guard
            let url = NSURL(string: link)
            else {return}
        contentMode = mode
        NSURLSession.sharedSession().dataTaskWithURL(url,response,error) -> Void in
            guard
                let httpURLResponse = response as? NSHTTPURLResponse where httpURLResponse.statusCode == 200,let mimeType = response?.MIMEType where mimeType.hasPrefix("image"),let data = data where error == nil,let image = UIImage(data: data)
                else { return }
            dispatch_async(dispatch_get_main_queue()) { () -> Void in
                self.image = image
            }
        }).resume()
    }
}

然后你可以把这一行放在任何你想要的地方

cell.cellPhoto.downloadedFrom(link: "customImageUrl",contentMode: .ScaleAspectFit) //Try changing contentMode

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple 最新软件的错误和性能问题。
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只有5%的概率会遇到选择运营商界面且部分必须连接到iTunes才可以激活
一般在接外包的时候, 通常第三方需要安装你的app进行测试(这时候你的app肯定是还没传到app store之前)。
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应用变灰了。那么接下来我们看一下Flutter是如何实现的。Flutter中实现整个App变为灰色在Flutter中实现整个App变为灰色是非常简单的,只需要在最外层的控件上包裹ColorFiltered,用法如下:ColorFiltered(颜色过滤器)看名字就知道是增加颜色滤镜效果的,ColorFiltered( colorFilter:ColorFilter.mode(Colors.grey, BlendMode.
flutter升级/版本切换
(1)在C++11标准时,open函数的文件路径可以传char指针也可以传string指针,而在C++98标准,open函数的文件路径只能传char指针;(2)open函数的第二个参数是打开文件的模式,从函数定义可以看出,如果调用open函数时省略mode模式参数,则默认按照可读可写(ios_base:in | ios_base::out)的方式打开;(3)打开文件时的mode的模式是从内存的角度来定义的,比如:in表示可读,就是从文件读数据往内存读写;out表示可写,就是把内存数据写到文件中;
文章目录方法一:分别将图片和文字置灰UIImage转成灰度图UIColor转成灰度颜色方法二:给App整体添加灰色滤镜参考App页面置灰,本质是将彩色图像转换为灰度图像,本文提供两种方法实现,一种是App整体置灰,一种是单个页面置灰,可结合具体的业务场景使用。方法一:分别将图片和文字置灰一般情况下,App页面的颜色深度是24bit,也就是RGB各8bit;如果算上Alpha通道的话就是32bit,RGBA(或者ARGB)各8bit。灰度图像的颜色深度是8bit,这8bit表示的颜色不是彩色,而是256
领导让调研下黑(灰)白化实现方案,自己调研了两天,根据网上资料,做下记录只是学习过程中的记录,还是写作者牛逼
让学前端不再害怕英语单词(二),通过本文,可以对css,js和es6的单词进行了在逻辑上和联想上的记忆,让初学者更快的上手前端代码
用Python送你一颗跳动的爱心
在uni-app项目中实现人脸识别,既使用uni-app中的live-pusher开启摄像头,创建直播推流。通过快照截取和压缩图片,以base64格式发往后端。
商户APP调用微信提供的SDK调用微信支付模块,商户APP会跳转到微信中完成支付,支付完后跳回到商户APP内,最后展示支付结果。CSDN前端领域优质创作者,资深前端开发工程师,专注前端开发,在CSDN总结工作中遇到的问题或者问题解决方法以及对新技术的分享,欢迎咨询交流,共同学习。),验证通过打开选择支付方式弹窗页面,选择微信支付或者支付宝支付;4.可取消支付,放弃支付会返回会员页面,页面提示支付取消;2.判断支付方式,如果是1,则是微信支付方式。1.判断是否在微信内支付,需要在微信外支付。
Mac命令行修改ipa并重新签名打包
首先在 iOS 设备中打开开发者模式。位于:设置 - 隐私&安全 - 开发者模式(需重启)
一 现象导入MBProgressHUD显示信息时,出现如下异常现象Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_MBProgressHUD", referenced from: objc-class-ref in ViewController.old: symbol(s) not found for architecture x86_64clang: error: linker command failed wit
Profiles >> 加号添加 >> Distribution >> "App Store" >> 选择 2.1 创建的App ID >> 选择绑定 2.3 的发布证书(.cer)>> 输入描述文件名称 >> Generate 生成描述文件 >> Download。Certificates >> 加号添加 >> "App Store and Ad Hoc" >> “Choose File...” >> 选择上一步生成的证书请求文件 >> Continue >> Download。
今天有需求,要实现的功能大致如下:在安卓和ios端实现分享功能可以分享链接,图片,文字,视频,文件,等欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~声明:本博文章若非特殊注明皆为原创原文链接。