0

I have a UIView and inside that, I have added a UILabel and UICollectionView. The UICollectionView scrolls horizontally. But the issue is that when I run the app, the UICollectionView offset is set in such a way that the first cell is partly hidden. If I scroll to the right then I can see the contents of the first cell. But when I let go it bounces back to its original hidden state.

As you can see here the first cell has 2 UIViews but only the second one is visible.

sideways hidden cell layout front view of hidden cell

When I scroll right, this is how it looks:

The, I... 10, is the cell that is getting hidden. I have added the elements programmatically, so could be a constraint issue. But I can't zero down on what could be causing it.

Here's my UICollectionViewCell:

class UserCountryCell: UICollectionViewCell {
    
    let countryNameLabel: UILabel
    let countryUserCountLabel: UILabel
    
    
    override init(frame: CGRect) {
        countryNameLabel = UILabel()
        countryUserCountLabel = UILabel()
        super.init(frame: frame)

        self.addSubview(countryNameLabel)
        countryNameLabel.translatesAutoresizingMaskIntoConstraints = false
        countryNameLabel.font = UIFont.boldSystemFont(ofSize: 13)
        countryNameLabel.textColor = .white
        
        self.addSubview(countryUserCountLabel)
        countryUserCountLabel.translatesAutoresizingMaskIntoConstraints = false
        countryUserCountLabel.font = UIFont.systemFont(ofSize: 13)
        countryUserCountLabel.textColor = .white
        
        NSLayoutConstraint.activate([
            countryNameLabel.trailingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
            countryNameLabel.heightAnchor.constraint(equalToConstant: 30),
            countryNameLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 5),
            countryNameLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 5),
//            countryNameLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 0),
            countryNameLabel.widthAnchor.constraint(equalToConstant: 20),

            countryUserCountLabel.leadingAnchor.constraint(equalTo: countryNameLabel.trailingAnchor, constant: 5),
            countryUserCountLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 5),
            countryUserCountLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 5),
            countryUserCountLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -5),
            countryUserCountLabel.heightAnchor.constraint(equalToConstant: 30),
            countryUserCountLabel.widthAnchor.constraint(equalToConstant: 40)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configureCell(countryName: String, countryUserCount: Int) {
        countryNameLabel.text = countryName
        countryUserCountLabel.text = String(countryUserCount)
    }
}
Parth
  • 2,682
  • 1
  • 20
  • 39
  • First, you should add and constrain subviews to the cell's `.contentView`, not to the cell itself. So, try changing your lines that say `self.addSubview(...)` to `self.contentView.addSubview(...)` and `... .constraint(equalTo: self. ...` to `... .constraint(equalTo: self.contentView. ...` and see if that fixes it. – DonMag Jan 11 '21 at 17:57

1 Answers1

1

OK - couple things...

As I said in my comment, add subviews and constraints to the cell's .contentView, not to the cell itself.

You do have a few mistakes in your constraints. You constrained the countryNameLabel.trailingAnchor to self.leadingAnchor ... that should be .leadingAnchor to .leadingAnchor.

Your .bottomAnchor constants should be negative.

If you want the labels' text to determine their widths, don't assign a .widthAnchor.

Try replacing your init with this:

override init(frame: CGRect) {
    countryNameLabel = UILabel()
    countryUserCountLabel = UILabel()
    super.init(frame: frame)
    
    contentView.addSubview(countryNameLabel)
    countryNameLabel.translatesAutoresizingMaskIntoConstraints = false
    countryNameLabel.font = UIFont.boldSystemFont(ofSize: 13)
    countryNameLabel.textColor = .white
    
    contentView.addSubview(countryUserCountLabel)
    countryUserCountLabel.translatesAutoresizingMaskIntoConstraints = false
    countryUserCountLabel.font = UIFont.systemFont(ofSize: 13)
    countryUserCountLabel.textColor = .white
    
    NSLayoutConstraint.activate([

        // needs to be .leadingAnchor to .leadingAnchor
        //countryNameLabel.trailingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
        countryNameLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5),

        countryNameLabel.heightAnchor.constraint(equalToConstant: 30),
        countryNameLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
        countryNameLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5),
        
        // if you want the label width to fit its text
        //  don't set the label's widthAnchor
        //countryNameLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 0),
        //countryNameLabel.widthAnchor.constraint(equalToConstant: 20),
        
        countryUserCountLabel.leadingAnchor.constraint(equalTo: countryNameLabel.trailingAnchor, constant: 5),
        countryUserCountLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
        countryUserCountLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5),
        countryUserCountLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5),
        countryUserCountLabel.heightAnchor.constraint(equalToConstant: 30),

        // if you want the label width to fit its text
        //  don't set the label's widthAnchor
        //countryUserCountLabel.widthAnchor.constraint(equalToConstant: 40)
    ])

}
DonMag
  • 69,424
  • 5
  • 50
  • 86
  • Hey thanks for pointing out the wrong constraint and location to place the subviews in. I had tried removing the width constraint for the country name label, but that did not help auto-sizing the cells. I tried returning CGSize.zero for cell size and set an estimated cell size for the layout of collection view. Maybe I will make another post about it. – Parth Jan 12 '21 at 08:59
  • Here's the new question: https://stackoverflow.com/questions/65680963/horizontal-scrolling-collection-view-cells-not-resizing-based-on-content-width – Parth Jan 12 '21 at 09:14
  • Also, this setup has a strange issue where the collection view shifts up on scrolling: https://stackoverflow.com/questions/65681344/horizontal-scrolling-collection-view-shifts-up-when-scrolled-in-parent-container – Parth Jan 12 '21 at 09:42