Uicollectionview Inside Tableviewcell Not Called

UICollectionView cellForItemAt not get called when I use a UICollectionView inside a UITableView cell on iOS 14

Check your layout code and make sure that at run time UICollectionView has a non-zero size (both width & height must be > 0).

In case any of width/height is zero, it doesn't need to display anything and hence it won't call your dataSource implementation for cellForItemAt:.

You can use View Hierarchy Debugger to check UICollectionView's width/height values at run time.

Can not Select CollectionView in TableView Cell

This is wrong:

class DayCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)

self.layer.cornerRadius = 7.calculated
self.addSubview(self._day) // <-- NO
self._day.snp.makeConstraints({
$0.center.equalTo(self)
})
}
}

Never add a subview to a cell. Say

self.contentView.addSubview(self._day)

Otherwise it is impossible to touch the _day interface.

UITableviewcell not displaying UICollectionView

The problem is, you didn't set the delegate and data source for your UICollectionView instance.

Highlighted in this picture shows they are not connected.

Sample Image

In your ConciergeCell class, make the following changes:

class ConciergeCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
static let ID = "conciergeCollection"

@IBOutlet weak var collectionView: UICollectionView!
private var concierge: Concierge

func awakeFromNib() {
super.awakeFromNib()

self.collectionView.delegate = self
self.collectionView.dataSource = self
}

func configure(withConciergeData concierge:Concierge) {
self.concierge = concierge
self.concierge.reloadData()
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.concierge.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
cell.displayContent(image: self.concierge[indexPath.row].image!, title: concierge[indexPath.row].name!)
cell.backgroundColor = UIColor.dark70
cell.layoutSubviews()
return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Collection view at row \(collectionView.tag) selected index path \(indexPath)")
}
}

And then, in the following function, before you return the [cell] array, call the configure(withConciergeData:) function with the instance of your concierge data like so:

extension ViewController : ExpandableDelegate {
func expandableTableView(_ expandableTableView: ExpandableTableView, expandedCellsForRowAt indexPath: IndexPath) -> [UITableViewCell]? {
let cell = tableView.dequeueReusableCell(withIdentifier: ConciergeCell.ID) as! ConciergeCell
cell.configure(withConciergeData: concierge)
return [cell]
}
}

Just a heads up, I typed in this code here. You might have some compiler errors if you copy and paste it into Xcode. Hope this helps.

didSelectItemAt from collectionView not getting called when the collectionView is inside a UITableView row

Your issue is related to adding subviews directly to UITableViewCell and not using contentView. You can read more about UITableViewCell internals here

UICollectionView inside UITableViewCell returning empty always even though shows as selected

You are trying to get a reusable cell in willMove(toParent parent: UIViewController?) , this is not going to return you a expected cell.

You need to get the cell , using a indexPath .

func cellForRow(at indexPath: IndexPath) -> UITableViewCell?

UICollectionView doesn't scroll inside UITableViewCell

You cannot scroll your collection view because it is outside the bounds of its superview. In your code, you have this line:

containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)

That makes your containerView height only around 20-pts, but you also have your collection view as a subview of containerView.

Here is how your code looks for me (pretty much as-is):

Sample Image

And, I cannot scroll the collection view.

You can confirm it is outside the containerView bounds by giving containerView a background color (I used cyan):

Sample Image

You can also confirm it by setting containerView.clipsToBounds = true:

Sample Image

Now, we don't even see the collection view.

You have a couple other constraint issues, but they don't really relate to being unable to scroll the collection view.

Your layout is also a little confusing, in that you have your Categories label outside your containerView... it seems it would make much more sense to have that label + the "See All" button + the collection view all inside the containerView.

I made a few edits to your CategoriesTableViewCellCollectionViewCell which resolves that issue -- and I think is close to your ultimate goal. You may need to do a little tweaking, but hopefully it will give you a good direction.

class CategoriesTableViewCellCollectionViewCell: UITableViewCell, UICollectionViewDelegateFlowLayout {

let categories = ["italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food", "italian food", "chinese food", "korean food"]

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
layoutUI()
selectionStyle = .none
}

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

lazy var containerView: UIView = {
let containerView = UIView()
containerView.backgroundColor = .clear
containerView.translatesAutoresizingMaskIntoConstraints = false
return containerView
}()

lazy var categoriesNameLabel: UILabel = {
let categoriesNameLabel = UILabel()
categoriesNameLabel.text = "Categories"
categoriesNameLabel.textColor = .gray // .customDarkGray()
categoriesNameLabel.textAlignment = .left
categoriesNameLabel.font = UIFont(name: "AvenirNext-Regular", size: 14)
categoriesNameLabel.translatesAutoresizingMaskIntoConstraints = false
return categoriesNameLabel
}()

lazy var seeAllCategoriesButton: UIButton = {
let seeAllCategoriesButton = UIButton()
seeAllCategoriesButton.setTitle("See all", for: .normal)
// seeAllCategoriesButton.setTitleColor(.CustomGreen(), for: .normal)
seeAllCategoriesButton.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 0.0, alpha: 1.0), for: .normal)
seeAllCategoriesButton.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 14)
seeAllCategoriesButton.translatesAutoresizingMaskIntoConstraints = false
seeAllCategoriesButton.addTarget(self, action: #selector(test), for: .touchUpInside)
return seeAllCategoriesButton
}()

@objc func test() {
print("Test worked")
}

lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .clear
collectionView.showsHorizontalScrollIndicator = false
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: "CategoriesCollectionViewCell")
return collectionView
}()

func setupContainerViewConstraints() {
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
// should not be constrained to categoriesNameLabel height
//containerView.heightAnchor.constraint(equalTo: categoriesNameLabel.heightAnchor)
// constrain 16-pts from bottom of cell
containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16)
])
}

func setupCategoriesNameLabelConstraints() {
NSLayoutConstraint.activate([
categoriesNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
// centerY to seeAllCategoriesButton
categoriesNameLabel.centerYAnchor.constraint(equalTo: seeAllCategoriesButton.centerYAnchor)
])
}

func setupSeeAllCategoriesButtonConstraints() {
NSLayoutConstraint.activate([
seeAllCategoriesButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
// constrain top to containerView top
seeAllCategoriesButton.topAnchor.constraint(equalTo: containerView.topAnchor)
])
}

func setupCollectionViewConstraints() {
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: seeAllCategoriesButton.bottomAnchor, constant: 0),
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16),
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
])
}

func addSubviews() {
// but categoriesNameLabel inside containerView
//addSubview(categoriesNameLabel)
addSubview(containerView)
containerView.addSubview(categoriesNameLabel)
containerView.addSubview(seeAllCategoriesButton)
containerView.addSubview(collectionView)
}

func layoutUI() {
addSubviews()
setupCollectionViewConstraints()
setupContainerViewConstraints()
setupCategoriesNameLabelConstraints()
setupSeeAllCategoriesButtonConstraints()
}

}

The result looks like this - and you can see that I have scrolled the collection view a bit:

Sample Image



Related Topics



Leave a reply



Submit