I am trying to create infinite calendar using swift 3.0 + xib. I have 2 .xib files: JKCalendar (collectionView) and JKCalenderCell(date cell). When I use my JKCalendar class on UIView i get calendar that fits this view size, but my cells are off. What is more I cant set correct number of columns using FlowDelegate.
class JKCalendarCell: UICollectionViewCell {
#IBOutlet var test: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override init(frame: CGRect) {
super.init(frame: frame)
let view = Bundle.main.loadNibNamed("JKCalendarCell", owner: self, options: nil)?[0] as! UIView
addSubview(view)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
class JKCalendar: UIView,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
#IBOutlet var collectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
self.collectionView.frame = self.bounds
self.collectionView.translatesAutoresizingMaskIntoConstraints = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadXib()
}
func loadXib(){
let view = UINib(nibName: "JKCalendar", bundle: nil).instantiate(withOwner: self, options: nil)[0]
addSubview(view as! UIView)
self.collectionView.register(UINib(nibName: "JKCalendarHeader" , bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "JKCalenderHeader")
self.collectionView.register(JKCalendarCell.self, forCellWithReuseIdentifier: "JKCalendarCell")
}
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 42
}
public func numberOfSections(in collectionView: UICollectionView) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "JKCalendarCell", for: indexPath) as! JKCalendarCell
return cell
}
public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let cell = cell as! JKCalendarCell
let dayNumber = countDayNumber()
cell.test.text = "\(dayNumber)"
cell.backgroundColor = UIColor.white
if indexPath.row % 2 == 0 {
cell.backgroundColor = UIColor.red
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (collectionView.frame.width / 7.0 )
return CGSize(width: width, height: width)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
}
JKCalendar.xib
My ViewContoller
And this is what I get after running.
I want 7 cells/row with label in center. I used red color cells with label on right to show how much they are off
Related
I am trying to create a similar layout to the App store. I have got one collection view that is vertical and inside of it each row is another collection view that is horizontal.
I am trying to use dynamic height so the cell can increase its height based on the content inside. However that never works, it only works when i use sizeForItemAt function to explicitly set it. I would like to also be able to control the width
I have looked at many previous questions such as: UICollectionView, full width cells, allow autolayout dynamic height? however no answer worked for me.
I am really confused on what i am doing wrong.
import UIKit
class HomeViewController: UICollectionViewController {
public override func viewDidLoad() {
super.viewDidLoad()
let collectionViewLayout = UICollectionViewFlowLayout()
collectionViewLayout.scrollDirection = .vertical
collectionViewLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
collectionView.collectionViewLayout = collectionViewLayout
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView?.register(HorizontalCollectionView.self, forCellWithReuseIdentifier: HorizontalCollectionView.reuseIdentifier)
}
public override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
public override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 4
}
public override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HorizontalCollectionView.reuseIdentifier, for: indexPath) as? HorizontalCollectionView {
return cell
}
return UICollectionViewCell()
}
}
HorizontalCollectionView.swift
import UIKit
class HorizontalCollectionView: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
static let reuseIdentifier = "HorizontalCollectionView"
var cellSpancolumns: CGFloat?
override init(frame: CGRect) {
super.init(frame: frame)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
collectionView.delegate = self
collectionView.dataSource = self
addSubview(collectionView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented - Storyboards are not used.")
}
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
let collectionView = UICollectionView(frame: bounds, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.showsHorizontalScrollIndicator = false
return collectionView
}()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
if (indexPath as NSIndexPath).section == 0 {
cell.backgroundColor = UIColor.blue
} else {
cell.backgroundColor = UIColor.red
}
return cell
}
}
I have a view called HorizontalMenuCollectionView on which I am loading the collection view. I can use it just by hooking it up with any view (from identity inspector).
All are working perfectly. But now I want to set the background color of the first item cell when this view will be loaded at the beginning. But the cell background color is not changing. What am I missing here?
This is the function where I am trying to set the background color of the item cell
func selectinitialCell() {
let selectedIndexPath = IndexPath(item: 0, section: 0)
let cell = menuCollectionView.dequeueReusableCell(withReuseIdentifier: "HorizontalMenuCollectionViewCell", for: selectedIndexPath) as! HorizontalMenuCollectionViewCell
cell.backgroundColor = UIColor.blue.withAlphaComponent(0.05)
menuCollectionView.reloadData()
}
This is the full HorizontalMenuCollectionView:
import UIKit
protocol HorizontalMenuCollectionViewDelegate {
func didSelectItemAtIndexPath(title: String)
}
class HorizontalMenuCollectionView: UIView {
var horizontalMenuCollectionViewDelegate : HorizontalMenuCollectionViewDelegate!
#IBOutlet weak var menuCollectionView: UICollectionView!
var objectArray = [String?]()
var isFirstTimeGettingCalled = true
//This initializer will call from code
override init(frame: CGRect) {
super.init(frame: frame)
self.initialization()
}
//This initializer will call from XIB
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialization()
}
func initialization() {
let view = Bundle.main.loadNibNamed("HorizontalMenuCollectionView", owner: self, options: nil)![0] as? UIView
view?.frame = self.bounds
self.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.addSubview(view!)
registerNib()
selectinitialCell()
}
func selectinitialCell() {
let selectedIndexPath = IndexPath(item: 0, section: 0)
let cell = menuCollectionView.dequeueReusableCell(withReuseIdentifier: "HorizontalMenuCollectionViewCell", for: selectedIndexPath) as! HorizontalMenuCollectionViewCell
cell.backgroundColor = UIColor.blue.withAlphaComponent(0.05)
menuCollectionView.reloadData()
}
func registerNib() {
let horizontalMenuCollectionViewCellNib = UINib(nibName: "HorizontalMenuCollectionViewCell", bundle: nil)
menuCollectionView.register(horizontalMenuCollectionViewCellNib, forCellWithReuseIdentifier: "HorizontalMenuCollectionViewCell")
}
}
extension HorizontalMenuCollectionView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return objectArray.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let text = NSAttributedString(string: objectArray[indexPath.row]!)
return CGSize(width: text.size().width + 80, height: self.bounds.height)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HorizontalMenuCollectionViewCell", for: indexPath) as! HorizontalMenuCollectionViewCell
cell.titleLabel.text = objectArray[indexPath.row]!
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor.blue.withAlphaComponent(0.05)
cell.selectedBackgroundView = backgroundView
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
menuCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
horizontalMenuCollectionViewDelegate.didSelectItemAtIndexPath(title: objectArray[indexPath.row]!)
}
}
Ans the view controller where I am accessing it
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var horizontalMenuCollectionView: HorizontalMenuCollectionView!
override func viewDidLoad() {
super.viewDidLoad()
horizontalMenuCollectionView.horizontalMenuCollectionViewDelegate = self
horizontalMenuCollectionView.objectArray = ["A", "AA", "AAA", "AAAA", "AAAAA"]
}
}
extension ViewController: HorizontalMenuCollectionViewDelegate {
func didSelectItemAtIndexPath(title: String) {
print("\(title)")
}
}
A full sample project is here.
Replace your func selectinitialCell() with the below one.
func selectinitialCell() {
menuCollectionView.performBatchUpdates({
self.menuCollectionView.reloadData()
}) { (finish) in
if finish{
let selectedIndexPath = IndexPath(row: 0, section: 0)
self.menuCollectionView.selectItem(at: selectedIndexPath, animated: false, scrollPosition: .left)
}
}
}
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.
I have a collectionView with a number of cells and when I load it I want to select a specific cell, show it as selected and scroll the collection view to the that selected cell's location without having to do the scrolling myself.
I can show the cell as selected but the scrolling doesn't seem to work from the provided function.
This is my attempt to doing it.
class RepsCellView: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
lazy var repsValuesCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.black
collectionView.showsHorizontalScrollIndicator = false
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
addSubview(repsValuesCollectionView)
//...
// Cell
let selectedIndex = IndexPath(item: 19, section: 0)
repsValuesCollectionView.selectItem(at: selectedIndex, animated: true, scrollPosition: [.centeredHorizontally, .centeredVertically])
}
// CollectionView DataSource Functions
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
return cell
}
}
Thanks in advance.
what ViewController event method are you using to run your code?
Anyway I could scroll it placing your code in the ViewController event method viewDidAppear method.
class CollectionViewController: UICollectionViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let cellToSelect = IndexPath(item: 99, section: 0)
self.collectionView?.scrollToItem(at: cellToSelect, at: [.centeredHorizontally, .centeredVertically], animated: true)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! RepsCellView
cell.setupViews() // added this line
return cell
}
}
I am interested in having a collectionview as a part of a collection view cell but for some reason cannot figure out how this would be done. Where would I implement the necessary methods for the cells collectionview?
There's an article that Ash Furrow wrote that explains how to put an UICollectionView inside an UITableViewCell. It's basically the same idea when using it inside an UICollectionViewCell.
Everything is done programatically. No storyboards.
I added a UICollectionView inside my UICollectionViewCell. I also show how to add again a UICollectionViewCell inside the created UICollectionView to have this result
import UIKit
class CategoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
private let cellId = "cell"
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let appsCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
return collectionView
}()
func setupViews() {
backgroundColor = .blue
addSubview(appsCollectionView)
appsCollectionView.delegate = self
appsCollectionView.dataSource = self
appsCollectionView.register(AppCell.self, forCellWithReuseIdentifier: cellId)
addConstrainstWithFormat("H:|-8-[v0]-8-|", views: appsCollectionView)
addConstrainstWithFormat("V:|[v0]|", views: appsCollectionView)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
return cell
}
}
class AppCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews(){
backgroundColor = .red
}
}
My UICollectionViewController
import UIKit
class FeaturedAppsController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let cellId = "cell"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
collectionView?.backgroundColor = .white
collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: cellId)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(view.frame.width, 150)
}
}
The whole explanation can be found and was developed by "Let´s build that app": https://www.youtube.com/watch?v=Ko9oNhlTwH0&list=PL0dzCUj1L5JEXct3-OV6itP7Kz3tRDmma
This is too late for this answer but it might help others. This is an example of UICollectionView inside a UICollectionViewCell.
Lets start by having a mainCollectionView. Then on each cell of this collection create and initialize a new UICollectionView and right place to do that is in this following delegate of UICollectionView
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath)
e.g I initialize the MainCollectionViewCell here and then MainCollectionViewCell handles the logic to create a new UICollectionView
guard let collectionViewCell = cell as? MainCollectionViewCell else { return }
collectionViewCell.delegate = self
let dataProvider = ChildCollectionViewDataSource()
dataProvider.data = data[indexPath.row] as NSArray
let delegate = ChildCollectionViewDelegate()
collectionViewCell.initializeCollectionViewWithDataSource(dataProvider, delegate: delegate, forRow: indexPath.row)
collectionViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
Here is the initializer on MainCollectionViewCell that creates a new UICollectionView
func initializeCollectionViewWithDataSource<D: protocol<UICollectionViewDataSource>,E: protocol<UICollectionViewDelegate>>(dataSource: D, delegate :E, forRow row: Int) {
self.collectionViewDataSource = dataSource
self.collectionViewDelegate = delegate
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .Horizontal
let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: flowLayout)
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseChildCollectionViewCellIdentifier)
collectionView.backgroundColor = UIColor.whiteColor()
collectionView.dataSource = self.collectionViewDataSource
collectionView.delegate = self.collectionViewDelegate
collectionView.tag = row
self.addSubview(collectionView)
self.collectionView = collectionView
collectionView.reloadData()
}
Hope that helps !!
I did an example for this and put in on github. It demonstrates the use UICollectionView inside a UICollectionViewCell.
https://github.com/irfanlone/Collection-View-in-a-collection-view-cell
Easiest solution for collectionview inside collectionview using storyboard and Swift 5
Please refer this link for nested collectionview example
import UIKit
class ParentViewController:UIViewController,UICollectionViewDataSource,UICollectionViewDelegate {
//MARK: Declare variable
//MARK: Decalare outlet
#IBOutlet weak var outerCollectionView: UICollectionView!
#IBOutlet weak var pageControl: UIPageControl!
let outerCount = 4
//MARK: Decalare life cycle methods
override func viewDidLoad() {
super.viewDidLoad()
pageControl.numberOfPages = outerCount
}
//MARK: Collection View delegate methods
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return outerCount
}
//MARK: Collection View datasource methods
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "OuterCell", for: indexPath) as! OuterCollectionViewCell
cell.contentView.backgroundColor = .none
return cell
}
//MARK:- For Display the page number in page controll of collection view Cell
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(origin: self.outerCollectionView.contentOffset, size: self.outerCollectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = self.outerCollectionView.indexPathForItem(at: visiblePoint) {
self.pageControl.currentPage = visibleIndexPath.row
}
}
}
class OuterCollectionViewCell: UICollectionViewCell ,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet weak var InnerCollectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
InnerCollectionView.delegate = self
InnerCollectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
6
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "InnerCell", for: indexPath) as! InnerCollectionViewCell
cell.contentView.backgroundColor = .green
return cell
}
}
class InnerCollectionViewCell: UICollectionViewCell{
}