Reputation: 93
I would like to create a collection view to be like on the picture
SO far I do have this code for my controller
class MainCollController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {
let cellId = "collectionCellId"
override func viewDidLoad() {
super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)
collectionView.register(Cell.self, forCellWithReuseIdentifier: cellId)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.grayBg
self.view.addSubview(collectionView)
_ = collectionView.anchor(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let width = UIScreen.main.bounds.width
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.itemSize = CGSize(width: width / 2, height: width / 2)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
collectionView.collectionViewLayout = layout
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width / 2 , height: 280)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! Cell
cell.backgroundColor = UIColor.cyan
cell.cellIndex = indexPath.row
return cell
}
}
And this one for the cell. I was thinking to check if indexPath.row is even or add and depends on it set a different constraints.
class Cell: UICollectionViewCell {
var cellIndex: Int? {
didSet {
if cellIndex! % 2 == 0 {
_ = productView.anchor(topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 0, leftConstant: 20, bottomConstant: 0, rightConstant: 8.5, widthConstant: 0, heightConstant: 264)
} else {
_ = productView.anchor(topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 0, leftConstant: 11.5, bottomConstant: 0, rightConstant: 19.5, widthConstant: 0, heightConstant: 264)
}
}
}
let productView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.white
view.layer.borderColor = UIColor(red:0.867, green:0.867, blue:0.867, alpha:1.000).cgColor
view.layer.borderWidth = 0.5
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(productView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
When I open my app it does look exactly how I need it to be, but when I start scrolling down and up everything gets mixed.
Can you please help me to sort it out. Thanks!
Upvotes: 0
Views: 122
Reputation: 121
Try this code...
extension YourVC: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemSpacing: CGFloat = 5 //set the spacing as needed
let itemSize = (collectionView.frame.width - (3 * itemSpacing)) / 2
return CGSize(width: itemSize, height: itemSize * 1.69)
}
}
Note: 1.69 is the height to width ratio that is have taken. (Means cell height is 1.69 times the width of itself.)
Upvotes: 1
Reputation: 535576
The layout you're trying to make, with fixed cell sizes and paddings and number of cells per row to form a regular grid, is not really what UICollectionViewFlowLayout is intended for. You'd be better off writing your own collection view layout, or at the very least subclassing UICollectionViewFlowLayout, to lay the cells out the way you want them.
Don't know how to get started? There are many grid layout examples out there that you can start with: do a Google search on "UICollectionView grid layout".
Upvotes: 1
Reputation: 4265
You need to implement these two functions to make a collectionView like you want:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(0,15,0,15)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 30
}
Feel free to play with the values for your purpose.
Upvotes: 1