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.
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):
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):
You can also confirm it by setting containerView.clipsToBounds = true
:
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:
Related Topics
Save The Exif Metadata Using The New PHPhotolibrary
How to Keep Animated Gifs Animated While Scrolling on iOS Devices
Revealviewcontroller() Always Returns Nil
Resize All Subview in Scrollviewdidzoom
Creating a First Launch Viewcontroller
iOS 8 Uitableview First Row Has Wrong Height
Uicollectionviewcompositionallayout - Center Items in Sections or Groups
Is There an iOS API for Accessing Call Logs
Can You Listen to Firestore Updates When iOS App Is in The Background
Error When Instantiating a UIfont in an Text Attributes Dictionary
Why Use Corebluetooth Connectperipheral Did Not Call Delegate Methods in iOS8
How to Draw a Uilabel with a Different Blend Mode in Draw(_ Rect: Cgrect) in Swift
Bootstrap Columns with Flexbox Are Not Taking Proper Width on iOS and Safari
How to Fix Broken Transform-Origin on iOS11 and Macos10.12 Safari
How to Create a Scnnode from a .Usdz
Xcode 8.3 Swift Version Error (Swift_Version) in Objective C Project