CollectionView delegate methods are not calling from TableViewCell - ios

Delegate isn't being called from tableViewCell. Here is UICollectionViewDelegate and UICollectionViewDataSource code
extension HomeVC:UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("ok")
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let lay = collectionViewLayout as! UICollectionViewFlowLayout
lay.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
lay.minimumInteritemSpacing = 0
lay.minimumLineSpacing = 0
collectionView.collectionViewLayout = lay
let size = (collectionView.frame.size.width-10) / 2
return CGSize(width: size, height: size)
}
}

swift 5
//MARK:- Tableview Datasource method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:"RecentLoanApplicationCell") as! RecentLoanApplicationCell
cell.collectionVC.delegate = self
cell.collectionVC.dataSource = self
cell.btnViewAll.addTarget(self, action: #selector(btnViewALLTap(button:)), for: .touchUpInside)
DispatchQueue.main.async {
cell.collectionVC.reloadData()
}
return cell
}
//MARK:- Tableview Cell in side custom cell Register for collectionView cell
class RecentLoanApplicationCell: UITableViewCell {
#IBOutlet var collectionVC:UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
self.collectionVC.register(UINib.init(nibName:"RecentLoanCollectionViewCell", bundle: nil), forCellWithReuseIdentifier:"RecentLoanCollectionViewCell")
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
// Same ControllerView call
//MARK:- Collection DataSource & Delegate
extension HomeViewController : UICollectionViewDelegate,UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:"RecentLoanCollectionViewCell", for: indexPath) as! RecentLoanCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
debugPrint("didSelectItemAt ==>\(indexPath.row)")
}

Here is the code how I done for same inside TableViewCell using collectionView and performed selection :
Code inside TableView datasource method :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BasicCarColorCell", for: indexPath) as! BasicCarColorCell
cell.dataSource = preloads.colors
cell.collectionViewSetup()
cell.delegate = self
return cell
}
Code for TableViewCell:
protocol BasicCarColorCellDelegate {
func colorCell(cell:BasicCarColorCell, didSelect color: Color)
}
class BasicCarColorCell: UITableViewCell {
var dataSource = Array<Color>()
var selectedColor = Color()
#IBOutlet weak var textView: RSKPlaceholderTextView!
#IBOutlet weak var guideLineMessage:UILabel!
#IBOutlet weak var collectionView: UICollectionView!
var delegate: BasicCarColorCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func collectionViewSetup() {
let nib = UINib(nibName: "BasicCarColorCollectionCell", bundle: nil)
self.collectionView.register(nib, forCellWithReuseIdentifier: "BasicCarColorCollectionCell")
let flowLayout = UICollectionViewFlowLayout()
flowLayout.minimumLineSpacing = 0
flowLayout.minimumInteritemSpacing = 0
flowLayout.scrollDirection = .horizontal
collectionView.collectionViewLayout = flowLayout
collectionView.dataSource = self
collectionView.delegate = self
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension BasicCarColorCell: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BasicCarColorCollectionCell", for: indexPath) as! BasicCarColorCollectionCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let height = collectionView.bounds.size.height-2
let width = height-20
return CGSize(width: width, height:height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 1, left: 10, bottom: 1, right: 10)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let color = self.dataSource[indexPath.item]
self.selectedColor = color
delegate?.colorCell(cell: self, didSelect: self.selectedColor)
collectionView.reloadData()
}
}
And to handle the selection of collectionView just implement the method of custom protocol written in TableViewCell in ViewController:
func colorCell(cell: BasicCarColorCell, didSelect color: Color) {
//self.selectedCarColor = color.value
}
You can do it in same pattern as per your need.
Hope it'll help!

You need to set datasource and delegate for collectionView, every time in Tableview delegate CellForRowAtIndexPath.

Related

Get the selected cells count in UICollectionView

How to get the selected cells count and selected cells array from UICollectionView, I need to set the limit of selection. Below is my code which is not working. Please guide. Thanks
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
let indexPaths = collectionView.indexPathsForSelectedItems!
print(indexPaths)
if let selectedItems = collectionView.indexPathsForSelectedItems {
if selectedItems.count >= 3 {
collectionView.deselectItem(at: indexPath as IndexPath, animated: true)
return false
}
}
return true
}
Above code when written in didSelect method returns only selected cell index but here just skip to last line
return true
You can use the shouldSelectItemAt delegate method from the UICollectionViewDelegate to achieve that:
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
return collectionView.indexPathsForSelectedItems?.count ?? 0 <= selectionLimit
}
A sample demo to demonstrate how it works:
class ViewController : UIViewController {
private var myCollectionView:UICollectionView?
private var selectionLimit = 4
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView()
view.backgroundColor = .white
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: UIScreen.main.bounds.width * 0.7, height: 60)
myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
myCollectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
myCollectionView?.backgroundColor = UIColor.white
myCollectionView?.allowsMultipleSelection = true
myCollectionView?.dataSource = self
myCollectionView?.delegate = self
view.addSubview(myCollectionView ?? UICollectionView())
self.view = view
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)
myCell.backgroundColor = UIColor.blue
return myCell
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Did select a cell at \(indexPath.row)")
let itemsLeftToSelect = selectionLimit - (collectionView.indexPathsForSelectedItems?.count ?? 0)
print("Have \(itemsLeftToSelect) items to select")
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
print("Did deselect a cell at \(indexPath.row)")
let itemsLeftToSelect = selectionLimit - (collectionView.indexPathsForSelectedItems?.count ?? 0)
print("Have \(itemsLeftToSelect) items to select")
}
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
return collectionView.indexPathsForSelectedItems?.count ?? 0 < selectionLimit
}
}
When you reach the selection limit, shouldSelectItemAt will return false and didSelectItemAt function will not be called anymore. On the other hand if you click on the already selected cell, didDeselectItemAt will be called and you will be called, and you are able to select + 1 cell again, as the number of selected items will decrease with 1. See also the debug logs in the example.
A better approach is model based.
In your data model add a property
var isSelected = false
and re-/set it accordingly when a cell is de-/selected.
Then you can simply count the selected data source items  – dataSource represents the data source array
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
return dataSource.filter{$0.isSelected}.count < 3
}
Further there is no need to deselect a row in this method as you are preventing the user from selecting more than 2 rows.

How to add Footer / Header in CollectionView

code Snippet
class TemporaryViewController: UIViewController {
#IBOutlet weak var itemCollectionView: UICollectionView! // Main Collection View
private var footerView: DashboardBottomViewCollectionViewCell?
override func viewDidLoad() {
super.viewDidLoad()
self.itemCollectionView.delegate = self
self.itemCollectionView.dataSource = self
self.itemCollectionView.register(UINib(nibName: nibParameter.DASHBOARD_CENTER_NIB, bundle: nil), forCellWithReuseIdentifier: nibParameter.DASHBOARD_CENTER_NIB)
self.itemCollectionView.register(UINib(nibName: "DashboardBottomViewCollectionViewCell", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "DashboardBottomViewCollectionViewCell")
}}
extension TemporaryViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
return nil
case UICollectionView.elementKindSectionFooter:
let footerView = itemCollectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "DashboardBottomViewCollectionViewCell", for: indexPath) as! DashboardBottomViewCollectionViewCell
self.footerView = footerView
self.footerView?.contentView?.clipsToBounds = true
footerView?.dashboardBottomDelegate = self
footerView?.clipsToBounds = true
return footerView!
default:
return headerView!
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: 600, height: 300.0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: 100.0, height: 300.0)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = -10 + (collectionView.frame.width)
return CGSize(width: width,
height: 90)
}
}
Footer Class to Show collection View
class DashboardBottomViewCollectionViewCell: UICollectionReusableView {
weak var dashboardBottomDelegate: DashboardBottomViewCollectionViewDelegate?
#IBOutlet weak var itemCollectionView: UICollectionView!
#IBOutlet weak var imageView: UIView!
var estimateWidth = 160.0
var cellMarginSize = 16.0
var contentView : DashboardBottomViewCollectionViewCell?
override init(frame: CGRect) {
super.init(frame: frame)
let contents = Bundle.main.loadNibNamed("DashboardBottomViewCollectionViewCell", owner: self, options: nil)?.first as! DashboardBottomViewCollectionViewCell
self.addSubview(contents)
contentView = contents
contents.itemCollectionView.register(UINib(nibName: nibParameter.DASHBOARD_PURCHASE_NIB, bundle: nil), forCellWithReuseIdentifier:nibParameter.DASHBOARD_PURCHASE_NIB)
contents.itemCollectionView.delegate = self
contents.itemCollectionView.dataSource = self
let flow = contents.itemCollectionView?.collectionViewLayout as! UICollectionViewFlowLayout
flow.minimumInteritemSpacing = CGFloat(self.cellMarginSize)
flow.minimumLineSpacing = CGFloat(self.cellMarginSize)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func reloadData() {
contentView?.itemCollectionView.reloadData()
}
}
extension DashboardBottomViewCollectionViewCell: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 15
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: nibParameter.DASHBOARD_PURCHASE_NIB, for: indexPath) as! RecentPurchaseCollectionViewCell
cell.purchaseLabel.text = "trainers.trainerName"
cell.imageView.sd_setImage(with: URL(string: "trainers.tarinerProfilePictureUrl" != nil ? "trainers.tarinerProfilePictureUrl" : ""), placeholderImage: UIImage.init(named: "tour_placeholder"), options: .handleCookies, completed: nil)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = 0 + (collectionView.frame.width / 1)
return CGSize(width: width,
height: 100)
}
}
extension DashboardBottomViewCollectionViewCell : UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
dashboardBottomDelegate?.didSelect(tem: indexPath.item)
}
}
As per the code, I can see this:
I can see a collectionView in Footer but can't change the orientation to vertical instead of the Grid view like this:
I am stuck and couldn't find any hint. Any hint would be appreciable. Thanks
Have you tried putting your setup code DashboardBottomViewCollectionViewCell.init(frame:) in awakeFromNib() instead?
override func awakeFromNib() {
super.awakeFromNib()
//setup cell and stuffs
}
Also call footerView?.reloadData() to reload the contents.

collectionView cell width not changing for different nib

I have a collection view which is nested inside of a table view cell. The first cell in the collection view is a button which allows users to create a new list. Its width is smaller than that of the main lists cells. I recently changed the code around so that the collectionView delegate and dataSource methods are in the tableViewController instead of the table view cell, however now the first cells width is not changing as it did before moving the code. This picture shows:
If I press into the blank space it is registering that I clicked the plus cell.
The code for all the collectionView delegate and dataSource methods:
extension ProfileTableViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("the media: \(usersLists.count)")
return usersLists.count + 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "addNewListCell", for: indexPath) as! addNewListCell
cell.currentUser = currentUser
return cell
}else{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! userListsCell
cell.layer.applySketchShadow()
cell.layer.cornerRadius = 20
cell.layer.masksToBounds = false
cell.currentUser = currentUser
cell.media = usersLists[indexPath.item-1]
return cell
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
if indexPath.item == 0 {
let size = CGSize(width: 80, height: 158)
return size
}else{
let size = CGSize(width: 158, height: 158)
return size
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.item == 0 {
//button
self.addListDelegate?.addNewItem()
}
}
I tested if changing any values in the size in sizeForItemAt would change the cell size and nothing changes in any cells
the table view methods which are in the ProfileTableViewController class and not the extension:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "profileCell", for: indexPath) as! profileCell
cell.selectionStyle = .none
return cell
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let tableViewCell = cell as? profileCell else { return }
tableViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row) //this line sets the collectionView delegate and datasouce so that I can have all of the collectionView methods in this class
}
and this is the code inside of the tableViewCell
protocol addListCollectionDelegate: class {
func addNewItem()
}
class profileCell: UITableViewCell, UICollectionViewDelegate {
#IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
collectionView.register(UINib(nibName: "usersLists", bundle: nil), forCellWithReuseIdentifier: "listCell")
collectionView.register(UINib(nibName: "newListCell", bundle: nil), forCellWithReuseIdentifier: "addNewListCell")
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setCollectionViewDataSourceDelegate
<D: UICollectionViewDataSource & UICollectionViewDelegate>
(dataSourceDelegate: D, forRow row: Int) {
collectionView.delegate = dataSourceDelegate
collectionView.dataSource = dataSourceDelegate
collectionView.reloadData()
}
}
Does anyone know how to change the width of the first cell since sizeForItemAt is not changing the size? Thanks
You forgot to add this protocol: UICollectionViewDelegateFlowLayout
It is required when you want to return custom size for an item.
Also improve your code like below:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "addNewListCell", for: indexPath) as! addNewListCell
cell.currentUser = currentUser
return cell
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! userListsCell
cell.layer.applySketchShadow() // Write this line in cell class
cell.layer.cornerRadius = 20 // Write this line in cell class
cell.layer.masksToBounds = false // Write this line in cell class
cell.currentUser = currentUser
cell.media = usersLists[indexPath.item - 1]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
return indexPath.item == 0 ? CGSize(width: 80, height: 158) : CGSize(width: 158, height: 158)
}
Try to use UICollectionViewDelegateFlowLayout method. In Xcode 11 or later, you need to set Estimate Size to none from Xib.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout:
UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let padding: CGFloat = 170
let collectionViewSize = advertCollectionView.frame.size.width - padding
return CGSize(width: collectionViewSize/2, height: collectionViewSize/2)
}

swift : tableViewcell initialization

I have a custom UITableViewCell class which has a collectionview inside. In this class there's a varaible "nbElements" which contain the number of collectionview cells to display. I want to know how I can initialize the value of nbElements when I create a tableview cell with dequeueReusableCell?
Here is the code of the custom tableview cell:
class CustomTableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
var nbElements = Int!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.collectionView.register(UINib(nibName: "CustomCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "customCollectionViewCell")
self.collectionViewHeightConstraint.constant = self.collectionView.collectionViewLayout.collectionViewContentSize.height
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return nbElements
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCollectionViewCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellWidth = (self.collectionView.frame.width / 2.0) - 1
let size = CGSize.init(width: cellWidth, height: cellWidth)
return size;
}
}
Here is the code when I create a tableview cell:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customTableViewCell", for: indexPath) as! CustomTableViewCell
cell.nbElements = 4
return cell
}
Regards.
Trigger reload of collectionView whenever the nbElements is set.
var nbElements = Int! {
didSet {
collectionView.reloadData()
}
}

CollectionView inside another CollectionViewCell

I am trying to create collectionView inside another collectionViewCell. I can get the cell of outer collectionView however, compiler is not executing inner cell. How can I get both the cells?
P.S I am new at this.
CollectionViewController Class:
class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout{
#IBOutlet var collectionView1: UICollectionView!
var coll2 = CollectionViewCell()
override func viewDidLoad() {
super.viewDidLoad()
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 150)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)as! CollectionViewCell
cell.backgroundColor = UIColor.black
return cell
}
}
CollectionViewCell CLass:
class CollectionViewCell: UICollectionViewCell {
#IBOutlet var collectionView2: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView2.frame.width, height: 150)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: "cell2", for: indexPath)as! CollectionViewCell2
cell1.backgroundColor = UIColor.red
return cell1
}
enter image description here
}
set the delegates and data source of inner collection view to the first collection view cell.
override func awakeFromNib()
{
super.awakeFromNib()
// Initialization code
self.collectionView2?.delegate = self
self.collectionView2?.dataSource = self
}
The reason why CollectionViewCell is not setting up the collectionView2 is because you didn't set delegate and dataSource properties of collectionView2 to the instance of CollectionViewCell.
I have created a method called setupViews in CollectionViewCell so that it can be called when you are dequeuing a CollectionViewCell in CollectionViewController so that the delegate and dataSource are being setup properly.
class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 150)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)as! CollectionViewCell
cell.backgroundColor = UIColor.black
cell.setupViews() // added this call
return cell
}
}
class CollectionViewCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var collectionView2: UICollectionView!
// added this method
func setupViews() {
collectionView2.delegate = self
collectionView2.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView2.frame.width, height: 150)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: "cell2", for: indexPath)
cell1.backgroundColor = UIColor.red
return cell1
}
}

Resources