简体   繁体   English

应该配置自定义CollectionViewCell的ImageView为零

[英]ImageView of a custom CollectionViewCell is nil when it should be configured

I have a tableViewCell with a collectionView , collectionView's cells are custom ones, they contains just a imageView . 我有一个带有collectionViewtableViewCellcollectionView's cells是自定义的,它们只包含一个imageView

Here is my test project 这是我的测试项目

Here are DataSource required methods from my CollectionView class : 以下是我的CollectionView class中的DataSource所需方法:

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
}

When I try to set image for cell's imageView I get this error : 当我尝试为单元格的imageView设置图像时,我收到此error

fatal error: unexpectedly found nil while unwrapping an Optional value 致命错误:在展开Optional值时意外发现nil

I have checked image , it isn't nil , but testImageView is, I get this error when I try to set image to collectionViewCell's testImageView. 我已经检查过image ,它不是nil ,但是testImageView是,当我尝试将图像设置为collectionViewCell的testImageView时,我收到此错误。 How can I fix it? 我该如何解决? EDIT1 EDIT1 在此输入图像描述

Here is method called from tableViewController to fill collectionView's listItem 这是从tableViewController调用的方法,用于填充collectionView的listItem

func load(listItem: [String]) {
    self.listItems = listItem
    reloadData()

}

Also if I remove code from collectionView cellForItemAt indexPath with this one all is working fine 此外,如果我从collectionView cellForItemAt indexPath删除代码,这一切都工作正常

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath)
let imageView = UIImageView(image:UIImage(named: listItems[indexPath.row]))

cell.backgroundView = imageView

You have mistaken your two view controllers. 你错了你的两个视图控制器。 Your IB outlet is connected to a cell in a different view controller. 您的IB插座连接到不同视图控制器中的单元。 I mean you can have multiple views in different controllers connected to a same IBOutlet, but in your case the one that loads first is not connected, so that is why it crashes. 我的意思是你可以在连接到同一个IBOutlet的不同控制器中拥有多个视图,但在你的情况下,首先加载的那个没有连接,所以这就是它崩溃的原因。

This is the cell your outlet was connected to. 这是您的插座所连接的单元格。 这是您的插座所连接的单元格。

This is that you are trying to load (but did not connect IBOutlet to image view): 这是您尝试加载(但没有将IBOutlet连接到图像视图):

在此输入图像描述

Just in case you want to use code instead.. 以防您想使用代码而不是..

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 http://imgur.com/o7O7Plw

在此输入图像描述

maybe the "testImageView" outlet variable is not connected from the interface builder or there is no CollectionViewCell with reuseIdentifier "ImageCell". 也许“testImageView”出口变量没有从界面构建器连接,或者没有带有reuseIdentifier“ImageCell”的CollectionViewCell。 Check whether cell is nil or not using LLDB po command. 使用LLDB po命令检查单元格是否为零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM