应配置的自定义 CollectionViewCell 的 ImageView 为 nil
Posted
技术标签:
【中文标题】应配置的自定义 CollectionViewCell 的 ImageView 为 nil【英文标题】:ImageView of a custom CollectionViewCell is nil when it should be configured 【发布时间】:2016-10-23 14:19:36 【问题描述】:我有一个tableViewCell
和一个collectionView
,collectionView's cells
是自定义的,它们只包含一个imageView
。
Here is my test project
这里是DataSource
我的CollectionView class
所需的方法:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell
let image = UIImage(named: listItems[indexPath.row])
cell.testImageView.image = image
return cell
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return listItems.count
当我尝试为单元格的 imageView 设置图像时,我得到了这个error
:
致命错误:在展开可选值时意外发现 nil
我检查了image
,不是nil
,而是testImageView
,当我尝试将图像设置为collectionViewCell 的testImageView 时出现此错误。
我该如何解决?
编辑1
这是从tableViewController
调用来填充collectionView 的listItem
的方法
func load(listItem: [String])
self.listItems = listItem
reloadData()
另外,如果我用这个从collectionView cellForItemAt indexPath
中删除代码,一切正常
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath)
let imageView = UIImageView(image:UIImage(named: listItems[indexPath.row]))
cell.backgroundView = imageView
【问题讨论】:
testImageView,它是作为 IBOutlet 从界面构建器添加的吗? 你连接了image view的插座吗? @Ahmad F 是的,它是 @Midhun MP 是的,我做到了 所以检查 listItems 数组,它是否已实例化并包含元素? 它必须被实例化,否则不会显示任何单元格。它也可以通过强制转换正确地出列。它可能为空的唯一方法是插座。重新启动 XCode 并检查插座是否已设置。确保没有错别字。确保插座很弱:@IBOutlet weak var testImageView: UIImageView?
【参考方案1】:
你弄错了你的两个视图控制器。您的 IB 插座连接到不同视图控制器中的单元。我的意思是你可以在连接到同一个 IBOutlet 的不同控制器中拥有多个视图,但在你的情况下,首先加载的那个没有连接,所以这就是它崩溃的原因。
这是您的插座连接到的单元格。
这是您尝试加载(但未将 IBOutlet 连接到图像视图):
【讨论】:
哦,真的,复制粘贴方法失败了)抱歉浪费了时间( @astrolka BTW,请注意,您混合 Objective-C 和 swift 的方式有点奇怪。这种方法有什么特别的原因吗? 当我尝试做同样的事情但在 obj-c 上没有调用任何数据源方法时,here for more info:D 这听起来绝对是个错误。你不应该无缘无故地混用 Objective-C 和 Swift。老实说,您的代码一团糟,我建议您重新开始。你没有得到正确的 MVC,你查看的是你的数据源。 MVC 的重点是您的数据和视图通过控制器进行通信。出于某种原因,所有这些都嵌入到表格视图中,这很奇怪。您的数据源方法没有被调用的原因是您可能忘记将控制器设置为表格视图的数据源 实际上我无法弄清楚如何将我的数据与控制器分开,这就是为什么我将数据存储在控制器中,据我所知这不是一个坏习惯,是吗?如果你给我一个如何使用 MVC 的好例子,我会很高兴的【参考方案2】:以防万一您想改用代码..
import UIKit
class ImageCell : UICollectionViewCell
private var imageView: UIImageView!
private var descLabel: UILabel!
public var image: UIImage?
get
return self.imageView.image
set
self.imageView.image = newValue
public var imageDesc: String?
get
return self.descLabel.text
set
self.descLabel.text = newValue
override init(frame: CGRect)
super.init(frame: frame)
self.initControls()
self.setTheme()
self.doLayout()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
self.initControls()
self.setTheme()
self.doLayout()
override func awakeFromNib()
super.awakeFromNib()
func initControls()
self.imageView = UIImageView()
self.descLabel = UILabel()
func setTheme()
self.imageView.contentMode = .scaleAspectFit
self.descLabel.numberOfLines = 1
self.descLabel.lineBreakMode = .byWordWrapping
self.descLabel.textAlignment = .center
self.descLabel.textColor = UIColor.black
self.contentView.backgroundColor = UIColor.white
func doLayout()
self.contentView.addSubview(self.imageView)
self.contentView.addSubview(self.descLabel)
self.imageView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 5).isActive = true
self.imageView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -5).isActive = true
self.imageView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 0).isActive = true
self.descLabel.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 5).isActive = true
self.descLabel.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -5).isActive = true
self.descLabel.topAnchor.constraint(equalTo: self.imageView.bottomAnchor, constant: 5).isActive = true
self.descLabel.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -5).isActive = true
for view in self.contentView.subviews
view.translatesAutoresizingMaskIntoConstraints = false
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
private var collectionView: UICollectionView!
private var dataSource: Array<String>!
override func viewDidLoad()
super.viewDidLoad()
self.initDataSource()
self.initControls()
self.setTheme()
self.registerClasses()
self.doLayout()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
func initDataSource()
self.dataSource = ["Image1", "Image2", "Image3", "Image4", "Image5", "Image6"]
func initControls()
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 117, height: 125)
layout.invalidateLayout()
self.collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
self.collectionView.delegate = self
self.collectionView.dataSource = self
func setTheme()
self.collectionView.backgroundColor = UIColor.clear
self.edgesForExtendedLayout = UIRectEdge(rawValue: 0)
self.view.backgroundColor = UIColor.blue
func registerClasses()
self.collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "ImageCellIdentifier")
func doLayout()
self.view.addSubview(self.collectionView)
self.collectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.collectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
self.collectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
for view in self.view.subviews
view.translatesAutoresizingMaskIntoConstraints = false
func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return self.dataSource.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCellIdentifier", for: indexPath) as! ImageCell
let imageName = self.dataSource[indexPath.row]
cell.image = UIImage(named: imageName)
cell.imageDesc = imageName
return cell
http://imgur.com/o7O7Plw
【讨论】:
【参考方案3】:也许“testImageView”出口变量没有从界面构建器连接,或者没有带有reuseIdentifier“ImageCell”的CollectionViewCell。使用 LLDB po 命令检查 cell 是否为 nil。
【讨论】:
如果没有reuseIdentifier "ImageCell" 那么dequeCell方法会报错 已连接,重用标识符正常且单元格不为零,我真的无法弄清楚这里出了什么问题((( @astrolka 你的单元格是在 Storyboard 中还是在 nib/xib 文件中设计的? @IlyaLapan 在 Storyboard 中,几分钟后我将添加项目 @astrolka ...尝试从图像名称中删除“.png”,同时将它们添加到 listItems 数组中。我已经多次遇到这种错误。我认为这应该可行。以上是关于应配置的自定义 CollectionViewCell 的 ImageView 为 nil的主要内容,如果未能解决你的问题,请参考以下文章
Feign自定义配置和编写Feign的Spring boot 插件
使用 UITableViewAutomaticDimension 显示多行标签的自定义单元格