Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create UICollectionViewCell programmatically

I'm trying to create UICollectionView programatically. I need to add labels inside the cells, so I Created CollectionViewCell class.

This is the class:

import UIKit  class MyCollectionViewCell: UICollectionViewCell {      override init(frame: CGRect) {         super.init(frame: frame)     }      required init?(coder aDecoder: NSCoder) {         fatalError("init(coder:) has not been implemented")     } } 

And this is the collectionView implementation class:

import UIKit  class TwoViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {      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", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"]      override func viewDidLoad() {         super.viewDidLoad()         let flowLayout = UICollectionViewFlowLayout()         let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)         collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)          collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell")         collectionView.delegate = self         collectionView.dataSource = self         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) as! MyCollectionViewCell         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)     }         } 

The error happens when the cell produced:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {     let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellReuseIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell 

The error is:

Could not cast value of type 'UICollectionViewCell' (0x1033cc820) to 'CollectionViewProgramatically.MyCollectionViewCell' (0x1015a4f88). 
like image 305
s_s Avatar asked Sep 11 '16 17:09

s_s


People also ask

How do I make UICollectionView programmatically?

To create a UICollectionView programmatically, I will create a new instance of UICollectionView by giving it a UICollectionViewFlowLayout as a parameter. var myCollectionView:UICollectionView? The above collection view will not display any items however.

How do I create a collection view?

Select the Main storyboard from the file browser. Add a CollectionView by pressing command shift L to open the storyboard widget window. Drag the collectionView onto the main view controller. Add constraints to the UICollectionView widget to ensure that the widget fills the screen on all devices.

What is UICollectionViewFlowLayout?

A layout object that organizes items into a grid with optional header and footer views for each section.


2 Answers

Try to copy and paste this code into your xcode, it should work

// //  HomeVIewController.swift //  Photolancer // //  Created by Lee SangJoon  on 9/8/16. //  Copyright © 2016 Givnite. All rights reserved. //  import UIKit   class HomeViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {        var collectionview: UICollectionView!     var cellId = "Cell"      override func viewDidLoad() {         super.viewDidLoad()          // Create an instance of UICollectionViewFlowLayout since you cant         // Initialize UICollectionView without a layout         let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()         layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)         layout.itemSize = CGSize(width: view.frame.width, height: 700)          collectionview = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)         collectionview.dataSource = self         collectionview.delegate = self         collectionview.registerClass(FreelancerCell.self, forCellWithReuseIdentifier: cellId)         collectionview.showsVerticalScrollIndicator = false         collectionview.backgroundColor = UIColor.whiteColor()         self.view.addSubview(collectionview)      }      func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {         return 10     }       func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {         let cell = collectionview.dequeueReusableCellWithReuseIdentifier(cellId, forIndexPath: indexPath) as! FreelancerCell         return cell     }   }         class FreelancerCell: UICollectionViewCell {       let profileImageButton: UIButton = {         let button = UIButton()         button.backgroundColor = UIColor.whiteColor()         button.layer.cornerRadius = 18         button.clipsToBounds = true         button.setImage(UIImage(named: "Profile"), forState: .Normal)          button.translatesAutoresizingMaskIntoConstraints = false         return button     }()       let nameLabel: UILabel = {         let label = UILabel()         label.font = UIFont.systemFontOfSize(14)         label.textColor = UIColor.darkGrayColor()         label.text = "Bob Lee"         label.translatesAutoresizingMaskIntoConstraints = false         return label     }()       let distanceLabel: UILabel = {         let label = UILabel()         label.textColor = UIColor.lightGrayColor()         label.font = UIFont.systemFontOfSize(14)         label.text = "30000 miles"         label.translatesAutoresizingMaskIntoConstraints = false         return label     }()      let pricePerHourLabel: UILabel = {         let label = UILabel()         label.textColor = UIColor.darkGrayColor()         label.font = UIFont.systemFontOfSize(14)         label.text = "$40/hour"         label.translatesAutoresizingMaskIntoConstraints = false         return label     }()        let ratingLabel: UILabel = {         let label = UILabel()         label.textColor = UIColor.lightGrayColor()         label.font = UIFont.systemFontOfSize(14)         label.text = "4.9+"         label.translatesAutoresizingMaskIntoConstraints = false         return label     }()       let showCaseImageView: UIImageView = {         let imageView = UIImageView()         imageView.backgroundColor = UIColor.whiteColor()         imageView.image = UIImage(named: "Profile")         imageView.translatesAutoresizingMaskIntoConstraints = false         return imageView     }()       let likesLabel: UILabel = {         let label = UILabel()         label.textColor = UIColor.lightGrayColor()         label.font = UIFont.systemFontOfSize(14)         label.text = "424 likes"         label.translatesAutoresizingMaskIntoConstraints = false         return label     }()       let topSeparatorView: UIView = {         let view = UIView()         view.backgroundColor = UIColor.darkGrayColor()         view.translatesAutoresizingMaskIntoConstraints = false         return view     }()      let bottomSeparatorView: UIView = {         let view = UIView()         view.backgroundColor = UIColor.darkGrayColor()         view.translatesAutoresizingMaskIntoConstraints = false         return view     }()       let likeButton: UIButton = {         let button = UIButton()         button.setTitle("Like", forState: .Normal)         button.titleLabel?.font = UIFont.systemFontOfSize(18)         button.setTitleColor(UIColor.darkGrayColor(), forState: .Normal)         button.translatesAutoresizingMaskIntoConstraints = false         return button     }()      let hireButton: UIButton = {         let button = UIButton()         button.setTitle("Hire", forState: .Normal)         button.titleLabel?.font = UIFont.systemFontOfSize(18)         button.setTitleColor(UIColor.darkGrayColor(), forState: .Normal)         button.translatesAutoresizingMaskIntoConstraints = false         return button     }()       let messageButton: UIButton = {         let button = UIButton()         button.setTitle("Message", forState: .Normal)         button.titleLabel?.font = UIFont.systemFontOfSize(18)         button.setTitleColor(UIColor.darkGrayColor(), forState: .Normal)         button.translatesAutoresizingMaskIntoConstraints = false         return button     }()        let stackView: UIStackView = {         let sv = UIStackView()         sv.axis  = UILayoutConstraintAxis.Horizontal         sv.alignment = UIStackViewAlignment.Center         sv.distribution = UIStackViewDistribution.FillEqually         sv.translatesAutoresizingMaskIntoConstraints = false;         return sv     }()         override init(frame: CGRect) {         super.init(frame: frame)          addViews()     }         func addViews(){         backgroundColor = UIColor.blackColor()          addSubview(profileImageButton)         addSubview(nameLabel)         addSubview(distanceLabel)         addSubview(pricePerHourLabel)         addSubview(ratingLabel)         addSubview(showCaseImageView)         addSubview(likesLabel)          addSubview(topSeparatorView)         addSubview(bottomSeparatorView)          // Stack View         addSubview(likeButton)         addSubview(messageButton)         addSubview(hireButton)         addSubview(stackView)           profileImageButton.leftAnchor.constraintEqualToAnchor(leftAnchor, constant: 5).active = true         profileImageButton.topAnchor.constraintEqualToAnchor(topAnchor, constant: 10).active = true         profileImageButton.heightAnchor.constraintEqualToConstant(36).active = true         profileImageButton.widthAnchor.constraintEqualToConstant(36).active = true          nameLabel.leftAnchor.constraintEqualToAnchor(profileImageButton.rightAnchor, constant: 5).active = true         nameLabel.centerYAnchor.constraintEqualToAnchor(profileImageButton.centerYAnchor, constant: -8).active = true         nameLabel.rightAnchor.constraintEqualToAnchor(pricePerHourLabel.leftAnchor).active = true          distanceLabel.leftAnchor.constraintEqualToAnchor(nameLabel.leftAnchor).active = true         distanceLabel.centerYAnchor.constraintEqualToAnchor(profileImageButton.centerYAnchor, constant: 8).active = true         distanceLabel.widthAnchor.constraintEqualToConstant(300)          pricePerHourLabel.rightAnchor.constraintEqualToAnchor(rightAnchor, constant: -10).active = true         pricePerHourLabel.centerYAnchor.constraintEqualToAnchor(nameLabel.centerYAnchor).active = true          // Distance depeneded on the priceLabel and distance Label         ratingLabel.rightAnchor.constraintEqualToAnchor(pricePerHourLabel.rightAnchor).active = true         ratingLabel.centerYAnchor.constraintEqualToAnchor(distanceLabel.centerYAnchor).active = true          showCaseImageView.topAnchor.constraintEqualToAnchor(profileImageButton.bottomAnchor, constant: 10).active = true         showCaseImageView.widthAnchor.constraintEqualToAnchor(widthAnchor).active = true         showCaseImageView.heightAnchor.constraintEqualToConstant(UIScreen.mainScreen().bounds.width - 20).active = true          likesLabel.topAnchor.constraintEqualToAnchor(showCaseImageView.bottomAnchor, constant: 10).active = true         likesLabel.leftAnchor.constraintEqualToAnchor(profileImageButton.leftAnchor).active = true          topSeparatorView.topAnchor.constraintEqualToAnchor(likesLabel.bottomAnchor, constant: 10).active = true         topSeparatorView.widthAnchor.constraintEqualToAnchor(widthAnchor).active = true         topSeparatorView.heightAnchor.constraintEqualToConstant(0.5).active = true          stackView.addArrangedSubview(likeButton)         stackView.addArrangedSubview(hireButton)         stackView.addArrangedSubview(messageButton)          stackView.topAnchor.constraintEqualToAnchor(topSeparatorView.bottomAnchor, constant: 4).active = true         stackView.widthAnchor.constraintEqualToAnchor(widthAnchor).active = true         stackView.centerXAnchor.constraintEqualToAnchor(centerXAnchor).active = true          bottomSeparatorView.topAnchor.constraintEqualToAnchor(stackView.bottomAnchor, constant: 4).active = true         bottomSeparatorView.widthAnchor.constraintEqualToAnchor(widthAnchor).active = true         bottomSeparatorView.heightAnchor.constraintEqualToConstant(0.5).active = true       }        required init?(coder aDecoder: NSCoder) {         fatalError("init(coder:) has not been implemented")     }  } 
like image 189
Bob Lee Avatar answered Oct 02 '22 12:10

Bob Lee


Your problem lies here. In your viewDidLoad(), you're registering your collectionView cell twice. You are registering the collectionview's cell to your custom cell class in the first line and then in the second line you are registering it to the class UICollectionViewCell.

 collectionView.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)  collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell") 

Just remove the second line and your code should work.

like image 30
ebby94 Avatar answered Oct 02 '22 14:10

ebby94