layout icon indicating copy to clipboard operation
layout copied to clipboard

Creating a custom UICollectionViewCell

Open vegidio opened this issue 5 years ago • 2 comments

I'm trying to create a custom UICollectionViewCell, but I'm having some problems. Here is what I'm doing:

  1. I created a cell layout called MyCustomCell.xml:
<UICollectionViewCell>

    <UILabel
        outlet="labelName"
        text="Name" />

</UICollectionViewCell>
  1. I created a custom UICollectionViewCell called MyCustomCollectionViewCell.swift that reads the layout above:
import Layout
import UIKit

class MyCustomCollectionViewCell: UICollectionViewCell, LayoutLoading
{
    @IBOutlet private weak var labelName: UILabel?
    var layoutNode: LayoutNode?

    override init(frame: CGRect) {
        super.init(frame: frame)
        loadLayout(named: "MyCustomCell.xml")
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        // Ensure layout is updated after screen rotation, etc
        self.layoutNode?.view.frame = self.bounds

        // Update frame to match layout
        self.frame.size = self.intrinsicContentSize
    }

    public override var intrinsicContentSize: CGSize {
        return layoutNode?.frame.size ?? .zero
    }
}

Then I tried to use this custom cell in my UICollectionView. My collection view also uses Layout and it's created like this:

  1. This is the layout file:
<UICollectionView
    outlet="collectionView"
    backgroundColor="#ffffff">

    <MyCustomCollectionViewCell reuseIdentifier="cell" />

</UICollectionView>
  1. And this the class that loads the layout above:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCellNode(withIdentifier: "cell", for: indexPath)
    return cell.view as! MyCustomCollectionViewCell
}

But after I do all this, I get the error message UICollectionViewCells must be created by UICollectionView in MyCustomCollectionViewCell.xml

My idea is to reuse MyCustomCollectionViewCell in different UICollectionViews so, how can I prevent the error above?

Thanks.

vegidio avatar Oct 22 '18 07:10 vegidio

@vegidio calling loadLayout(named: "...") loads the contents of that xml file as a subview of the view that called it. The root node in your MyCustomCell.xml file is a UICollectionViewCell, and you are loading it inside a subclass of UICollectionViewCell, so you are effectively trying to mount one cell inside another one.

It's fine to load the contents of a custom cell from an xml file like this, but you should either remove the root <UICollectionViewCell> node from the xml, or change it to a plain <UIView>.

nicklockwood avatar Oct 22 '18 12:10 nicklockwood

@nicklockwood Thanks for the explanation!

I removed the <UICollectionViewCell> from MyCustomCell.xml and I don't get the red error message anymore, but my cells are completely empty, even though I left a UILabel in the layout file.

I inspected the view (please see screenshot attached) and I noticed that there's nothing there, so I have the impression that the views were not loaded from the XML file into the UICollectionView, so I suspect that the code in my class MyCustomCollectionViewCell.swift that I posted before, might be wrong:

screenshot 2018-10-22 at 18 16 50

Can you see something that I might be missing?

Thanks!

vegidio avatar Oct 22 '18 16:10 vegidio