1

I have been stuck on this weird problem for a little while and cannot seem to figure it out.

Setup

  • A is a UICollectionView
  • Bs are A's UICollectionViewCells
  • C is a UICollectionView added as a subview of B when the user taps in B

    +------------------------------+
    |A                             |
    |                              |
    | +----------+    +----------+ |
    | |B         |    |B         | |
    | |----------|    |          | |
    | |          |    |          | |
    | |C         |    |          | |
    | +----------+    +----------+ |
    +------------------------------+
    

Issue

When initializing C's UICollectionViewFlowLayout scroll direction property to .horizontal, and scrolling past the second cell, C's cells are vanishing.

As a bonus C itself is vanishing from the UI: the user is again able to tap into the cell, which performs all the actions done on C's usual removal. When tapping again to normally re-show it, actions triggered on C's displaying are fired but C is still visually nowhere to be found.

The issue does not happen when scroll direction is set to .vertical.

Has anyone encountered a similar issue or any clue as to what's going on here?

Thanks in advance.


EDIT Actual implementation

(B)

import UIKit

class CollectionViewCell: UICollectionViewCell {

    //...

    private let cellId = "cellId"

    private lazy var label: UILabel = {

        return CollectionViewCell._label()
    }()

    fileprivate lazy var gallery: UICollectionView = {

        return CollectionViewCell._gallery()
    }()

    //...

    override init(frame: CGRect) {
        super.init(frame: frame)

        isOpaque = true
        clipsToBounds = true
        layer.borderWidth = 1.5
        layer.cornerRadius = 8

        // ...
    }

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

    private func onSwitchDisplayGallery(_ isDiplaying: Bool) {

        switch isDiplaying {

        case true:

            addSubview(label)
            label.topAnchor.constraint(equalTo: topAnchor).isActive = true
            label.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
            label.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
            label.heightAnchor.constraint(equalToConstant: frame.height / 5.25).isActive = true

            gallery.register(NestedCollectionViewCell.self, forCellWithReuseIdentifier: cellId)
            gallery.delegate = self
            addSubview(gallery)
            gallery.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
            gallery.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
            gallery.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
            gallery.heightAnchor.constraint(equalTo: heightAnchor, constant: -frame.height / 5.25).isActive = true

        case false:

            print("removed cv")
            // ...
        }
    }

    //...
}

extension CollectionViewCell: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        return gallery.frame.size
    }
}


private extension CollectionViewCell {

    class func _gallery() -> UICollectionView {

        let layout = UICollectionViewFlowLayout()

        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        layout.scrollDirection = .horizontal

        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)

        cv.isPagingEnabled = true
        cv.showsHorizontalScrollIndicator = false
        cv.translatesAutoresizingMaskIntoConstraints = false
        return cv
    }

    class func _label() -> UILabel {

        let label = UILabel()

        label.font = UIFont(name: "Montserrat-Regular", size: 15)
        label.textColor = .white
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }
}

(C)

import UIKit

class NestedCollectionViewCell: UICollectionViewCell {

    private let containerView = NestedCollectionViewCell._containerView()

    override init(frame: CGRect) {
        super.init(frame: frame)

        isOpaque = true
        clipsToBounds = true
        backgroundColor = .white

        addSubview(containerView)
        containerView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        containerView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
        containerView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
        containerView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true

        //...
    }

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

private extension NestedCollectionViewCell {

    class func _containerView() -> UIImageView {

        let view = UIImageView()

        view.contentMode = .scaleAspectFill
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }
}

EDIT 2 I have tried Nick's answer here.

When the scroll direction is set to .vertical, everything is normal.

When it is set to .horizontal C displays no cell...

Community
  • 1
  • 1
Herakleis
  • 513
  • 5
  • 21

1 Answers1

0

Silly, silly rookie mistake. Leaving this here if anyone else needs glasses like I do :)

The collection view did not have an horizontal constraint...

addSubview(gallery)
gallery.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
gallery.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

Correcting this to

addSubview(gallery)
gallery.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
gallery.leftAnchor.constraint(equalTo: leftAnchor).isActive = true

fixed it (obviously).

Herakleis
  • 513
  • 5
  • 21