tutorial how example didselectitematindexpath collection swift uicollectionview uicollectionviewcell

swift - how - Cómo crear UICollectionViewCell programáticamente



uicollectionview swift 4 (4)

Cambié la respuesta de Bob Lee por Swift 4

import UIKit class noNibCollectionViewController: 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.register(FreelancerCell.self, forCellWithReuseIdentifier: cellId) collectionview.showsVerticalScrollIndicator = false collectionview.backgroundColor = UIColor.white self.view.addSubview(collectionview) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 10 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionview.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! FreelancerCell return cell } } class FreelancerCell: UICollectionViewCell { let profileImageButton: UIButton = { let button = UIButton() button.backgroundColor = UIColor.white button.layer.cornerRadius = 18 button.clipsToBounds = true button.setImage(UIImage(named: "Profile"), for: .normal) button.translatesAutoresizingMaskIntoConstraints = false return button }() let nameLabel: UILabel = { let label = UILabel() label.font = UIFont.systemFont(ofSize: 14) label.textColor = UIColor.darkGray label.text = "Bob Lee" label.translatesAutoresizingMaskIntoConstraints = false return label }() let distanceLabel: UILabel = { let label = UILabel() label.textColor = UIColor.lightGray label.font = UIFont.systemFont(ofSize: 14) label.text = "30000 miles" label.translatesAutoresizingMaskIntoConstraints = false return label }() let pricePerHourLabel: UILabel = { let label = UILabel() label.textColor = UIColor.darkGray label.font = UIFont.systemFont(ofSize: 14) label.text = "$40/hour" label.translatesAutoresizingMaskIntoConstraints = false return label }() let ratingLabel: UILabel = { let label = UILabel() label.textColor = UIColor.lightGray label.font = UIFont.systemFont(ofSize: 14) label.text = "4.9+" label.translatesAutoresizingMaskIntoConstraints = false return label }() let showCaseImageView: UIImageView = { let imageView = UIImageView() imageView.backgroundColor = UIColor.white imageView.image = UIImage(named: "Profile") imageView.translatesAutoresizingMaskIntoConstraints = false return imageView }() let likesLabel: UILabel = { let label = UILabel() label.textColor = UIColor.lightGray label.font = UIFont.systemFont(ofSize: 14) label.text = "424 likes" label.translatesAutoresizingMaskIntoConstraints = false return label }() let topSeparatorView: UIView = { let view = UIView() view.backgroundColor = UIColor.darkGray view.translatesAutoresizingMaskIntoConstraints = false return view }() let bottomSeparatorView: UIView = { let view = UIView() view.backgroundColor = UIColor.darkGray view.translatesAutoresizingMaskIntoConstraints = false return view }() let likeButton: UIButton = { let button = UIButton() button.setTitle("Like", for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 18) button.setTitleColor(UIColor.darkGray, for: .normal) button.translatesAutoresizingMaskIntoConstraints = false return button }() let hireButton: UIButton = { let button = UIButton() button.setTitle("Hire", for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 18) button.setTitleColor(UIColor.darkGray, for: .normal) button.translatesAutoresizingMaskIntoConstraints = false return button }() let messageButton: UIButton = { let button = UIButton() button.setTitle("Message", for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 18) button.setTitleColor(UIColor.darkGray, for: .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.black 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.constraint(equalTo: leftAnchor, constant: 5).isActive = true profileImageButton.topAnchor.constraint(equalTo: topAnchor, constant: 10).isActive = true profileImageButton.heightAnchor.constraint(equalToConstant: 36).isActive = true profileImageButton.widthAnchor.constraint(equalToConstant: 36).isActive = true nameLabel.leftAnchor.constraint(equalTo: profileImageButton.rightAnchor, constant: 5).isActive = true nameLabel.centerYAnchor.constraint(equalTo: profileImageButton.centerYAnchor, constant: -8).isActive = true nameLabel.rightAnchor.constraint(equalTo: pricePerHourLabel.leftAnchor).isActive = true distanceLabel.leftAnchor.constraint(equalTo: nameLabel.leftAnchor).isActive = true distanceLabel.centerYAnchor.constraint(equalTo: profileImageButton.centerYAnchor, constant: 8).isActive = true distanceLabel.widthAnchor.constraint(equalToConstant: 300) pricePerHourLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -10).isActive = true pricePerHourLabel.centerYAnchor.constraint(equalTo: nameLabel.centerYAnchor).isActive = true // Distance depeneded on the priceLabel and distance Label ratingLabel.rightAnchor.constraint(equalTo: pricePerHourLabel.rightAnchor).isActive = true ratingLabel.centerYAnchor.constraint(equalTo: distanceLabel.centerYAnchor).isActive = true showCaseImageView.topAnchor.constraint(equalTo: profileImageButton.bottomAnchor, constant: 10).isActive = true showCaseImageView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true showCaseImageView.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.width - 20).isActive = true likesLabel.topAnchor.constraint(equalTo: showCaseImageView.bottomAnchor, constant: 10).isActive = true likesLabel.leftAnchor.constraint(equalTo: profileImageButton.leftAnchor).isActive = true topSeparatorView.topAnchor.constraint(equalTo: likesLabel.bottomAnchor, constant: 10).isActive = true topSeparatorView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true topSeparatorView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true stackView.addArrangedSubview(likeButton) stackView.addArrangedSubview(hireButton) stackView.addArrangedSubview(messageButton) stackView.topAnchor.constraint(equalTo: topSeparatorView.bottomAnchor, constant: 4).isActive = true stackView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true stackView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true bottomSeparatorView.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 4).isActive = true bottomSeparatorView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true bottomSeparatorView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }

Estoy tratando de crear UICollectionView programáticamente. Necesito agregar etiquetas dentro de las celdas, así que CollectionViewCell clase CollectionViewCell .

Esta es la clase:

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") } }

Y esta es la clase de implementación collectionView:

import UIKit class TwoViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate { let leftAndRightPaddings: CGFloat = 80.0 let numberOfItemsPerRow: CGFloat = 7.0 let screenSize: CGRect = UIScreen.mainScreen().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.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier) collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell") collectionView.delegate = self collectionView.dataSource = self collectionView.backgroundColor = UIColor.cyanColor() self.view.addSubview(collectionView) } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.items.count } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellReuseIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell cell.backgroundColor = UIColor.greenColor() return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { let width = (screenSize.width-leftAndRightPaddings)/numberOfItemsPerRow return CGSizeMake(width, width) } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets { return UIEdgeInsets(top: 20, left: 8, bottom: 5, right: 8) } }

El error ocurre cuando la célula produce:

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

El error es:

Could not cast value of type ''UICollectionViewCell'' (0x1033cc820) to ''CollectionViewProgramatically.MyCollectionViewCell'' (0x1015a4f88).


Intenta copiar y pegar este código en tu xcode, debería funcionar

// // 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") } }


Su problema radica aquí. En su viewDidLoad() , está registrando su celda de collectionView dos veces. Está registrando la celda de collectionview en su clase de celda personalizada en la primera línea y luego en la segunda línea la está registrando en la clase UICollectionViewCell .

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

Simplemente quite la segunda línea y su código debería funcionar.


override func awakeFromNib() { super.awakeFromNib() let overlayView = UIView() overlayView.backgroundColor = UIColor.red overlayView.frame = CGRect(x: 10, y: (350/2) - 50, width: 100, height: 100) self.addSubview(overlayView) }