import UIKit
private let reuseIdentifier = "NewCell"
class SeondViewController: UIViewController, UICollectionViewDelegateFlowLayout {
#IBOutlet var myNavBar: UINavigationBar!
var frutta: [String]!
override func viewDidLoad() {
super.viewDidLoad()
let margins = self.view.layoutMarginsGuide
let layout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 30, left: 10, bottom: 10, right: 10)
layout.scrollDirection = .vertical
let newCollectionView: UICollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
newCollectionView.dataSource = self
newCollectionView.delegate = self
newCollectionView.register(SecondTabCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
newCollectionView.reloadData()
newCollectionView.backgroundColor = UIColor.clear
newCollectionView.isHidden = false
newCollectionView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(newCollectionView)
frutta = ["Mele", "Olive", "Pere", "Noci", "Banane", "Kiwi", "Ananas"]
myNavBar.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
myNavBar.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
myNavBar.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
newCollectionView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
newCollectionView.topAnchor.constraint(equalTo: myNavBar.bottomAnchor).isActive = true
newCollectionView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
◦ newCollectionView.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.size.width / 2, height: collectionView.bounds.size.height / 3)
}
}
extension SecondViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return frutta.count
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! SecondTabCollectionViewCell
myCell.backgroundColor = UIColor.clear
myCell.secondCellLabel = UILabel()
myCell.secondCellLabel.frame.size = CGSize(width: myCell.bounds.width / 2, height: myCell.secondCellLabel.bounds.height / 2)
myCell.secondCellLabel.adjustsFontSizeToFitWidth = true
myCell.secondCellLabel.backgroundColor = UIColor.clear
myCell.secondCellLabel.textColor = UIColor.black
myCell.secondCellLabel.text = frutta[indexPath.item]
myCell.translatesAutoresizingMaskIntoConstraints = false
myCell.contentView.addSubview(myCell.secondCellLabel)
return myCell
}
}
extension SecondViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Hai premuto \(indexPath.row).")
}
}
import UIKit
class SecondTabCollectionViewCell: UICollectionViewCell {
var secondCellLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) non e stato implementato.")
}
}
myCell.secondCellLabel.frame.size = CGSize(width: myCell.bounds.width / 2, height: myCell.secondCellLabel.bounds.height / 2)
The above line is wrong in cellForItemAt, you put the height of label is myCell.secondCellLabel.bounds.height instead of myCell.bounds.height.
correct one is
myCell.secondCellLabel.frame.size = CGSize(width: myCell.bounds.width / 2, height: myCell.bounds.height / 2)
It is a little strange to be laying out a cell's internal views in cellForRowAtIndexPath, this should be done in the cell class itself. The basic problem is that you your UILabel is appearing in the top left corner of the cell and has a height of zero, so you cannot see it. I moved the code you had in cellForRowAtIndexPath into the cell itself.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! SecondTabCollectionViewCell
myCell.backgroundColor = UIColor.clear
myCell.secondCellLabel.text = frutta[indexPath.item]
return myCell
}
import UIKit
class SecondTabCollectionViewCell: UICollectionViewCell {
var secondCellLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .clear
label.textColor = .black
label.adjustsFontSizeToFitWidth = true
label.textAlignment = .center
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
configureViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func configureViews() {
addSubview(secondCellLabel)
}
override func layoutSubviews() {
super.layoutSubviews()
configureLayout()
}
private func configureLayout() {
let width = bounds.width / 2
let height = frame.height / 2
let size = CGSize(width: width, height: height)
let origin = CGPoint(x: width/2, y: height/2)
secondCellLabel.frame = CGRect(origin: origin, size: size)
}
}
Related
I noticed that Topics CollectionViewCell was not gone when I debugged. Why is that?
the cells are all correct but the collectionview is not available.
The link of the project is below. you can also look from there.
here I define cell.
extension ArticlesVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return models.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CollectionTableViewCell.identifier, for: indexPath) as! CollectionTableViewCell
cell.configure(with: models)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200
}
}
struct Model {
let text: String
let imageName: String
init(text: String, imageName: String) {
self.text = text
self.imageName = imageName
}
}
Here I define CollectionTableViewCell
class CollectionTableViewCell: UITableViewCell {
static let identifier = "CollectionTableViewCell"
var collectionView: UICollectionView?
var models = [Model]()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
collectionView?.register(TopicsCollectionViewCell.self, forCellWithReuseIdentifier: TopicsCollectionViewCell.identifier)
collectionView?.delegate = self
collectionView?.dataSource = self
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
contentView.addSubview(collectionView!)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
collectionView?.frame = contentView.bounds
}
func configure(with models: [Model]) {
self.models = models
collectionView?.reloadData()
}
}
extension CollectionTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return models.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TopicsCollectionViewCell.identifier, for: indexPath) as! TopicsCollectionViewCell
cell.configure(with: models[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 250, height: 250)
}
}
**This TopicsCollectionViewCell **
class TopicsCollectionViewCell: UICollectionViewCell {
static let identifier = "TopicsCollectionViewCell"
let titleLabel: UILabel = {
let label = UILabel()
label.text = "label"
return label
}()
let photoImage: UIImageView = {
let imageView = UIImageView()
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(titleLabel)
contentView.addSubview(photoImage)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
photoImage.frame = CGRect(x: 3,
y: 3,
width: contentView.width - 6,
height: 150)
titleLabel.frame = CGRect(x: 3,
y: photoImage.bottom + 5,
width: contentView.width - 6,
height: contentView.height - photoImage.height - 6)
}
public func configure(with model: Model) {
print(model)
self.titleLabel.text = model.text
self.photoImage.image = UIImage(named: model.imageName)
}
}
This link is project with github
During execution those lines are useless as collectionView? is nil
collectionView?.register(TopicsCollectionViewCell.self, forCellWithReuseIdentifier: TopicsCollectionViewCell.identifier)
collectionView?.delegate = self
collectionView?.dataSource = self
You need to reorder the code by initing the collectionView first
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
contentView.addSubview(collectionView!)
collectionView?.register(TopicsCollectionViewCell.self, forCellWithReuseIdentifier: TopicsCollectionViewCell.identifier)
collectionView?.delegate = self
collectionView?.dataSource = self
When using storyboards or nibs, outlets for CollectionViews are implicitly unwrapped, so accessing and configuring the collectionView is a straightforward process.
#IBOutlet var collectionView: UICollectionView!
When creating them programmatically we can do something like this:
var collectionView: UICollectionView!
Would this be the correct approach? Theres no guarantee that the collectionView will be initialised, so there's always the possibility for a crash. I would also like to avoid having an optional since I will be forced to unwrap it every time.
I always create them as computed, as there are some attributes you want to add to it. And often lazy as well so you can set dataSource and delegate. You also wants to add the collectionViewLayout in it's initializer. Hence i'm creating the UICollectionViewFlowLayout first.
private lazy var selectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.estimatedItemSize = CGSize(width: 64, height: 24)
layout.itemSize = CGSize(width: 64, height: 24)
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 12
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = .white
collectionView.showsHorizontalScrollIndicator = false
collectionView.contentInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
return collectionView
}()
Try this example
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let viewController = MyCollectionViewController()
viewController.modalPresentationStyle = .fullScreen
present(viewController, animated: true) {}
}
}
MyCollectionViewController.swift
import UIKit
class MyCollectionViewController: UIViewController {
var dataModels: [DataModel?] = [DataModel]()
private lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = .white
collectionView.showsHorizontalScrollIndicator = false
collectionView.contentInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
return collectionView
}()
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init() {
super.init(nibName: nil, bundle: nil)
self.view.backgroundColor = .yellow
let data = (0...10).map { value -> DataModel in
DataModel(name: "\(value)")
}
dataModels.append(contentsOf: data)
addCollectionView()
}
func addCollectionView() {
self.view.addSubview(self.collectionView)
self.collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
self.collectionView.translatesAutoresizingMaskIntoConstraints = false
self.collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
self.collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
self.collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
self.collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
}
extension MyCollectionViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? CollectionViewCell {
if let dataModel = dataModels[indexPath.row] {
print(">>>>\(dataModel.name)")
cell.nameLabel.text = dataModel.name
}
return cell
}
return UICollectionViewCell()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.dataModels.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
return CGSize(width: 200, height: 200)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets{
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
extension MyCollectionViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
}
class CollectionViewCell: UICollectionViewCell {
var storeBack = UIView()
var nameLabel = UILabel()
public override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
fileprivate func commonInit() {
self.contentView.addSubview(self.storeBack)
self.storeBack.backgroundColor=UIColor.green
self.storeBack.translatesAutoresizingMaskIntoConstraints = false
self.storeBack.topAnchor.constraint(equalTo: self.contentView.topAnchor).isActive = true
self.storeBack.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor).isActive = true
self.storeBack.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor).isActive = true
self.storeBack.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true
self.storeBack.addSubview(self.nameLabel)
self.nameLabel.textColor = .black
self.nameLabel.textAlignment = .center
self.nameLabel.numberOfLines = 0
nameLabel.font = UIFont.systemFont(ofSize: 20)
self.nameLabel.translatesAutoresizingMaskIntoConstraints = false
self.nameLabel.topAnchor.constraint(equalTo: storeBack.topAnchor).isActive = true
self.nameLabel.leadingAnchor.constraint(equalTo: storeBack.leadingAnchor).isActive = true
self.nameLabel.trailingAnchor.constraint(equalTo: storeBack.trailingAnchor).isActive = true
self.nameLabel.bottomAnchor.constraint(equalTo: storeBack.bottomAnchor).isActive = true
}
}
struct DataModel: Codable {
var name: String
}
I've gotten my cells to overlap by setting the minimumLineSpacing property of the collection views layout to negative. But, when I scroll and the cells are redrawn, they now overlap in the opposite direction. I've put pictures below.
How do I keep the cells overlapping as seen in the first picture when the collection view is scrolled and cells are redraw?
import UIKit
class PopularView: UIView {
let cellID = "cellID"
// MARK: - Views
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = -55 // -------Allows Overlap-----
layout.itemSize = CGSize(width: SCREEN_WIDTH, height: 185)
layout.minimumInteritemSpacing = 17
let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
view.backgroundColor = .white
return view
}()
// MARK: - Initializers
override init(frame: CGRect) {
super.init(frame: frame)
collectionView.dataSource = self
collectionView.register(PopularCell.self, forCellWithReuseIdentifier: cellID)
backgroundColor = .white
setupCollectionView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Setup
fileprivate func setupCollectionView() {
self.addSubview(collectionView)
collectionView.anchors(top: self.topAnchor, topPad: 0, bottom: self.bottomAnchor, bottomPad: 0, left: self.leftAnchor, leftPad: 0, right: self.rightAnchor, rightPad: 0, height: nil, width: nil)
collectionView.contentSize = CGSize(width: 700, height: 700)
}
}
extension PopularView: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 500
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! PopularCell
cell.background.backgroundColor = .random
return cell
}
}
Try this, that might help you:
1- Inside your Cells, you could define innerView inside your cell and set the frame to
let innerView:UIView = CGRect(x: 0,y: -overlapHeight,width: screenWidth, height:cell.height + overlapHeight)
cell?.contentView.addSubview(innerView)
2- Configure your cell during initialisation with this:
cell?.contentView.clipsToBounds = false
3- When loading cell, set the z-order:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.layer.zPosition = CGFloat(indexPath.row)
// configure your cell after here
}
You should be able to see the nested views inside your content view to have overlapping.
I have drafted a sample code, not looking perfectly, but will help you get started:
private let reuseIdentifier = "Cell"
private let overlapHeight:CGFloat = 100
class CustomCollectionCell:UICollectionViewCell {
var innerView:UIView?
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 300))
self.backgroundColor = .darkGray
let innerView = UIView(frame: CGRect(x: 0,y: -overlapHeight,width: UIScreen.main.bounds.width,height: overlapHeight + self.contentView.frame.height))
self.innerView = innerView
innerView.layer.cornerRadius = 20
self.contentView.addSubview(innerView)
self.contentView.clipsToBounds = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(color:UIColor?) {
innerView?.backgroundColor = color
}
}
import UIKit
private let reuseIdentifier = "Cell"
private let overlapHeight:CGFloat = 100
class CustomCollectionCell:UICollectionViewCell {
var innerView:UIView?
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .darkGray
let innerView = UIView(frame: CGRect(x: 0,y: -overlapHeight,width: UIScreen.main.bounds.width,height: overlapHeight + self.contentView.frame.height))
self.innerView = innerView
innerView.layer.cornerRadius = 20
self.contentView.addSubview(innerView)
self.contentView.clipsToBounds = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(color:UIColor?) {
innerView?.backgroundColor = color
}
}
class CollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.width, height: 190)
flowLayout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
flowLayout.scrollDirection = .vertical
flowLayout.minimumInteritemSpacing = 0.0
collectionView.collectionViewLayout = flowLayout
// Register cell classes
self.collectionView!.register(CustomCollectionCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 30
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.layer.zPosition = CGFloat(indexPath.row)
var color:UIColor?
switch indexPath.row % 4 {
case 0:
color = .purple
case 1:
color = .yellow
case 2:
color = .green
default:
color = .red
}
if let cell = cell as? CustomCollectionCell {
cell.configure(color: color)
}
return cell
}
}
Result:
I have got this Swift code
let collectionView = UICollectionView(frame: CGRect(x:0,y:0,width:0,height:0),
collectionViewLayout: UICollectionViewFlowLayout())
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(PostCell.self, forCellWithReuseIdentifier: cellId)
collectionView.delegate = self
collectionView.dataSource = self
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! PostCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
return UIEdgeInsets(top: 15, left: 5, bottom: 15, right: 5)
}
My goal is to make cell's height automatic based on it's content.I wanted to implement
if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}
and
let layoutHeight = UICollectionViewFlowLayout()
layoutHeight.estimatedItemSize = CGSize(width: 100, height: 100)
collectionView = UICollectionView(frame: CGRect(x:0,y:0,width:0,height:0), collectionViewLayout: layoutHeight)
But the first one made all cells 50x50 and the second one made them 100x100.Here is my PostCell class
class PostCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
designCell()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let CellprofileImage: UIImageView = {
let v = UIImageView()
v.layer.cornerRadius = 55
v.layer.masksToBounds = true
v.layer.borderWidth = 3
v.layer.borderColor = UIColor(white: 0.5, alpha: 1).cgColor
v.image = #imageLiteral(resourceName: "guitar")
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
func designCell(){
addSubview(CellprofileImage)
backgroundColor = .red
cellConstraints()
}
func cellConstraints(){
CellprofileImage.topAnchor.constraint(equalTo: self.topAnchor,constant:20).isActive = true
CellprofileImage.leftAnchor.constraint(equalTo: self.leftAnchor,constant:20).isActive = true
CellprofileImage.widthAnchor.constraint(equalToConstant: 310).isActive = true
CellprofileImage.heightAnchor.constraint(equalToConstant: 310).isActive = true
}
}
I want change color of circleView and text in label in cell in CollectionView using function.
Class of my Cell:
class CustomCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
var timerLabel:UILabel = {
let label = UILabel()
label.text = "5"
label.frame = CGRect(x: 200, y: 10, width: 60, height: 60)
label.backgroundColor = .white
label.textAlignment = NSTextAlignment.center
return label
}()
var circleView: UIView = {
let circleView = UIView()
circleView.frame = CGRect(x: 100, y: 10, width: 60, height: 60)
circleView.backgroundColor = .red
circleView.layer.cornerRadius = 30
circleView.layer.masksToBounds = true
return circleView
}()
func setupViews() {
backgroundColor = .white
addSubview(timerLabel)
addSubview(circleView)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViews()
}
}
Create CollectionView in VC:
func collectionViewSet() {
collectionView?.frame.size.height = (view.frame.height / 100) * 70
collectionView?.backgroundColor = .white
collectionView?.register(CustomCell.self, forCellWithReuseIdentifier: cellId)
}
//-------------- (CollectionView Configure) -------------------
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width:view.frame.width ,height: collectionView.frame.height / 6)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId , for: indexPath)
customCell.tag = indexPath.row + 1
return cell
}
And in my created func for example setColor() i want generate ranodm color (by UIColor) for CircleView and generate random number for TimerLable but only in one cell. For next cell I want generate another color and number. Is there any way to do that, i was trying use indexPath.row and func didselectedItemForindexPath but it didn't works at all. Maybe I did something wrong.
Ok I have found an answer. I post my code if someone will have similar problem :)
for x in 0...4{
let indexPath = IndexPath(row: x, section: 0)
guard let cell = collectionView?.cellForItem(at: indexPath) as? CustomCell else {
return
}
cell.circleView.backgroundColor = .blue
}
There are many, many examples of generating random colors and numbers out there - a quick search and you'll have plenty to choose from.
Once you've picked a couple, change your cellForItemAt function to:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId , for: indexPath)
customCell.tag = indexPath.row + 1
let randColor = myRandomColorFunc()
let randNumber = myRandomNumberFunc()
customCell.circleView.backgroundColor = randColor
customCell.timerLabel.text = "\(randNumber)"
return cell
}