This code has UICollectionView getting initiated and datasource being assigned. Cells are supposed to be rendered however the cells are not getting rendered. The DataSource is extracted out in this case.
import UIKit
class ViewController: UIViewController {
private let cellReuseIdentifier = "collectionCell"
override func viewDidLoad() {
super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)
let dataSource = DateSource()
collectionView.dataSource = dataSource
collectionView.backgroundColor = UIColor.cyan
self.view.addSubview(collectionView)
}
}
class DateSource:NSObject, UICollectionViewDataSource {
let leftAndRightPaddings: CGFloat = 80.0
let numberOfItemsPerRow: CGFloat = 7.0
let screenSize: CGRect = UIScreen.main.bounds
private let cellReuseIdentifier = "collectionCell"
var items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return self.items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier, for: indexPath)
cell.backgroundColor = UIColor.green
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let width = (screenSize.width-leftAndRightPaddings)/numberOfItemsPerRow
return CGSize(width: width, height: width)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
return UIEdgeInsets(top: 20, left: 8, bottom: 5, right: 8)
}
}
But this code renders the cells, when the datasource is sort of merged in the ViewController
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource {
private let cellReuseIdentifier = "collectionCell"
let leftAndRightPaddings: CGFloat = 80.0
let numberOfItemsPerRow: CGFloat = 7.0
let screenSize: CGRect = UIScreen.main.bounds
var items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
override func viewDidLoad() {
super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)
let dataSource = self
collectionView.dataSource = dataSource
collectionView.backgroundColor = UIColor.cyan
self.view.addSubview(collectionView)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return self.items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier, for: indexPath)
cell.backgroundColor = UIColor.green
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let width = (screenSize.width-leftAndRightPaddings)/numberOfItemsPerRow
return CGSize(width: width, height: width)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
return UIEdgeInsets(top: 20, left: 8, bottom: 5, right: 8)
}
}
I am a little lost here, was something to be instantiated inside DataSource, which was missed ?
In the first snippet, you've instantiated datasource in
viewDidLoad()
,This restricts the lifespan of your datasource object within the scope of that method. You need to declare your datasource as a member of your View Controller, as such;
Second snippet works since the datasource is self and it's scope will outlive the collectionView's.