Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIImageView最初不在UITableViewCell中显示图像_Ios_Swift_Uitableview_Uiimageview - Fatal编程技术网

Ios UIImageView最初不在UITableViewCell中显示图像

Ios UIImageView最初不在UITableViewCell中显示图像,ios,swift,uitableview,uiimageview,Ios,Swift,Uitableview,Uiimageview,我有一个从服务加载图像的UITableView。它通过NSURLSession.sharedSession().dataTaskWithURL获取URL并下载图像: NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data, _, error) -> Void in guard

我有一个从服务加载图像的
UITableView
。它通过
NSURLSession.sharedSession().dataTaskWithURL获取URL并下载图像:

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
内容模式为方面匹配

可见单元格的
UIImageView
最初显示为空(无图像),即使我已确认设置了图像。直到单元格在屏幕上/屏幕上滚动,单元格才会重新绘制(?)并显示图像

这似乎是个时间问题,但我想不出来。设置映像后,我尝试在
dispatch\u async
块中调用以下所有内容:

self.pictureView.setNeedsDisplay()
self.pictureView.setNeedsUpdateConstraints()
self.pictureView.setNeedsLayout()
self.pictureView.reloadInputViews()
这些都不能解决问题。是什么原因导致此图像仅在单元格滚出/滚入视图后显示

编辑: 可能需要注意的是,这是在nib和相关类中发生的。加载nib后,我开始下载。我想知道nib是否进行了布局,当我的图像被下载并设置在
UIImageView
上时,布局过程已经完成。然后,通过将单元格(包含nib)移离/移到屏幕上,单元格再次执行布局,所有内容都正确显示。只是一个猜测,我仍然坚持这一点

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

1) My
UIViewController
包含一个
UITableView

2) 此
UITableView
从名为PostCell的自定义
UITableViewCell
类加载单元格

3) PostCell的全部内容是从名为PostView的nib加载的单个视图(带有PostView类)。该加载在PostCell中的
init: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
observer,它根据
post
对象(上面的代码)中的URL启动图像下载。图像被下载并设置在名为
pictureView
UIImageView

编辑3:

以下是
表格视图(uxCELLFORROWATINDEXPATH:)
的代码:

编辑4:

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

因此,
UIImageView
的约束和大小似乎在图像加载时已经设置好,将其从屏幕上/从屏幕上拉出会导致某种类型的重画,从而正确调整图像的大小。如果我能以编程方式触发该重画,它会有所帮助,但请参阅上面我已经尝试过的内容

编辑6:

在这里,它正在发挥作用。注意,我在nib中设置了一个占位符图像。这似乎会导致图像在最初加载时显示,但显示在占位符的尺寸上。当屏幕正确显示时,在屏幕外短暂滚动会导致调整大小。

编辑7:

我在我的应用程序的其他地方使用PostView nib没有问题。加载时,图像大小正确。问题似乎只出现在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, completionHandler: { (data, 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

下载完成后,需要重新加载tableview数据。尝试调用
self.tableview.reloadData()
inside
dispatch\u async
block

另外,如果您想从URL异步下载图像,我建议您使用您看到了吗?这段视频可能会让你对你的问题有更多的了解

在WWDC会话中,他们使用
self.tableView.estimatedRowHeight=100.0您已完成的操作✅ 然后他们说你不需要任何来自表视图控制器的虚拟原型单元

然后问题是,当序列图像板加载表视图时,它会将
rowHeight
属性设置为来自xib/interface builder的值。要使用自动调整单元格大小,您需要设置
estimatedRowHeight
,并将
rowHeight
保留为默认值-
UITableViewAutomaticDimension
。(您已完成的操作)✅

self.tableView.rowHeight=UITableViewAutomaticDimension

⚠️新的问题是,第一个单元格在获得真正的行高之前加载。诀窍可能是在视图显示时强制重新加载表

[super viewDidAppear:animated]
[self.tableView reloadData]

如果这不起作用,那么可能是您无意中在某个内容上设置了显式的contentWidth/Height,导致其大小不正确❓❓

在查看了回复者的编辑过程(目前为8次)和更新之后,您似乎在init方法中遇到了导致错误的相同错误

应将注册nib的正确轨道归功于Prcela,但下面提供了一个更优雅的解决方案:

在nib文件中创建自定义表视图单元格的最简单方法(从iOS 5.0开始提供)是使用reg
[super viewDidAppear:animated]
[self.tableView reloadData]
[self.tableView registerNib:[UINib nibWithNibName:@"CueTableCell" bundle:nil] forCellReuseIdentifier:@"CueTableCell"];
CueTableCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CueTableCell"];
// setup cell
return cell;