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).
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")
}
}
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.
I changed Bob Lee answer for 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")
}
}
Response of Bob Lee updated to Swift 5.1
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.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, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionview.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath as 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 = NSLayoutConstraint.Axis.horizontal
sv.alignment = UIStackView.Alignment.center
sv.distribution = UIStackView.Distribution.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")
}
}
let collection :UICollectionView = {
let layout = UICollectionViewFlowLayout()
let collection = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: layout)
layout.scrollDirection = .horizontal
collection.translatesAutoresizingMaskIntoConstraints = false
collection.backgroundColor = .clear
return collection
}()
Related
I’m having trouble with my TexView here And this method textview.textAlignment = .naturalwon’t work I couldn’t figure out what the problem is here the text only stick to the left side no matter what the language is, now this textview is inside a collectionViewCell, I have tried to work around with the NSSting attributes didn’t work tried also to set the text alignment outside of the Cell didn’t work here is my code you will find messageTextView.textAlignment everywhere and all of this places I set it into didn’t work
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "orderReview", for: indexPath) as! OrderReviewCell
let order = orderreview[indexPath.item]
cell.textBubbleView.backgroundColor = UIColor(white: 0.95, alpha: 1)
cell.messageTextView.textAlignment = .natural
cell.messageTextView.textColor = .black
cell.messageTextView.text = order.order
cell.textBubbleViewRightAnchore?.isActive = false
cell.textBubbleViewLeftAnchore?.isActive = true
if let imgUrl = order.profileImg, imgUrl != "" {
cell.profileImg.loadImageUsingCacheWithUrlStringAndPlaceHolder(urlString: imgUrl)
}
cell.profileImg.isHidden = false
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 8, left: 0, bottom: 2, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var height: CGFloat = 80
let order = orderreview[indexPath.item]
if let text = order.order, text != "" {
height = estmatedFrameForText(text: text).height + 20
}
let width = UIScreen.main.bounds.width
return CGSize(width: width, height: height)
}
private func estmatedFrameForText(text: String) -> CGRect {
let size = CGSize(width: 250, height: 1000)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesDeviceMetrics)
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.natural
return NSAttributedString(string: text, attributes: [ NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.paragraphStyle: style ]).boundingRect(with: size, options: options, context: nil)
}
}
class OrderReviewCell: UICollectionViewCell{
let messageTextView: UITextView = {
let tv = UITextView()
tv.font = UIFont.systemFont(ofSize: 16)
tv.textAlignment = .natural
tv.backgroundColor = .clear
tv.isUserInteractionEnabled = false
tv.translatesAutoresizingMaskIntoConstraints = false
return tv
}()
let textBubbleView: UIView = {
let view = UIView()
view.layer.cornerRadius = 15
view.layer.masksToBounds = true
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let profileImg: UIImageView = {
let img = UIImageView(image: imageLiteral(resourceName: "ProfileHolder"))
img.contentMode = .scaleAspectFill
img.layer.cornerRadius = 16
img.layer.masksToBounds = true
img.translatesAutoresizingMaskIntoConstraints = false
return img
}()
var textBubbleViewWidth: NSLayoutConstraint?
var textBubbleViewRightAnchore: NSLayoutConstraint?
var textBubbleViewLeftAnchore: NSLayoutConstraint?
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(textBubbleView)
addSubview(messageTextView)
addSubview(profileImg)
setupLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupLayout(){
profileImg.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 8).isActive = true
profileImg.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
profileImg.widthAnchor.constraint(equalToConstant: 32).isActive = true
profileImg.heightAnchor.constraint(equalToConstant: 32).isActive = true
textBubbleView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
textBubbleView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true
textBubbleViewWidth = textBubbleView.widthAnchor.constraint(equalToConstant: 200)
textBubbleViewWidth?.isActive = true
textBubbleViewRightAnchore = textBubbleView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -8)
textBubbleViewRightAnchore?.isActive = true
textBubbleViewLeftAnchore = textBubbleView.leftAnchor.constraint(equalTo: profileImg.rightAnchor, constant: 8)
textBubbleViewLeftAnchore?.isActive = true
messageTextView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
messageTextView.rightAnchor.constraint(equalTo: self.textBubbleView.rightAnchor).isActive = true
messageTextView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true
messageTextView.leftAnchor.constraint(equalTo: self.textBubbleView.leftAnchor, constant: 8).isActive = true
}
}
I'm trying add a bottom border to a textfield inside a UICollectionViewCell, I registered the cell inside a view controller where my collection view is. But to set the size of the bottom border I need to the it own size, and I don't know how to do it inside the collection view cell, so Im trying to pass It to the view controller where It Is registered, but no success yet.
*Obs: I cut out some parts of the code because is not relevant.
UICollectionViewCell
class NameStepCell: UICollectionViewCell {
let safeAreaHolder: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let title: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.boldSystemFont(ofSize: 40)
label.text = "What is\nyour\nname?"
return label
}()
let txtFieldStack: UIStackView = {
let stack = UIStackView()
stack.translatesAutoresizingMaskIntoConstraints = false
stack.alignment = .center
stack.axis = .horizontal
stack.distribution = .fillEqually
stack.spacing = 20
return stack
}()
let nameField: UITextField = {
let txtFld = UITextField()
txtFld.keyboardType = UIKeyboardType.default
txtFld.textContentType = UITextContentType.name
txtFld.autocapitalizationType = UITextAutocapitalizationType.words
txtFld.autocorrectionType = .no
txtFld.textColor = UIColor.black
return txtFld
}()
let lastNameField: UITextField = {
let txtFld = UITextField()
txtFld.keyboardType = UIKeyboardType.default
txtFld.textContentType = UITextContentType.familyName
txtFld.autocapitalizationType = UITextAutocapitalizationType.words
txtFld.autocorrectionType = .no
txtFld.textColor = UIColor.black
return txtFld
}()
override init(frame: CGRect) {
super.init(frame: frame)
configuringView()
configuringTitle()
configuringTxtField()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configuringView(){
addSubview(safeAreaHolder)
safeAreaHolder.topAnchor.constraint(equalTo: topAnchor).isActive = true
safeAreaHolder.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16).isActive = true
safeAreaHolder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
safeAreaHolder.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true
}
func configuringTitle(){
safeAreaHolder.addSubview(title)
title.topAnchor.constraint(equalTo: safeAreaHolder.topAnchor, constant: 50).isActive = true
title.trailingAnchor.constraint(equalTo: safeAreaHolder.trailingAnchor).isActive = true
title.leadingAnchor.constraint(equalTo: safeAreaHolder.leadingAnchor).isActive = true
}
func configuringTxtField(){
safeAreaHolder.addSubview(txtFieldStack)
txtFieldStack.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 50).isActive = true
txtFieldStack.trailingAnchor.constraint(equalTo: safeAreaHolder.trailingAnchor).isActive = true
txtFieldStack.leadingAnchor.constraint(equalTo: safeAreaHolder.leadingAnchor).isActive = true
txtFieldStack.addArrangedSubview(nameField)
txtFieldStack.addArrangedSubview(lastNameField)
nameField.heightAnchor.constraint(equalToConstant: 45).isActive = true
lastNameField.heightAnchor.constraint(equalToConstant: 45).isActive = true
}
}
UIViewController
class SignupViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource{
let stepsCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .white
collectionView.contentInsetAdjustmentBehavior = UIScrollView.ContentInsetAdjustmentBehavior.never
collectionView.isPagingEnabled = true
collectionView.showsHorizontalScrollIndicator = false
collectionView.isScrollEnabled = false
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
stepsCollectionView.dataSource = self
stepsCollectionView.delegate = self
stepsCollectionView.register(NameStepCell.self, forCellWithReuseIdentifier: "nameStepId")
stepsCollectionView.register(GenderStepCell.self, forCellWithReuseIdentifier: "genderStepId")
stepsCollectionView.register(BirthdayStepCell.self, forCellWithReuseIdentifier: "birthdayStepId")
stepsCollectionView.register(EmailStepCell.self, forCellWithReuseIdentifier: "emailStepId")
stepsCollectionView.register(PasswordStepCell.self, forCellWithReuseIdentifier: "passwordStepId")
view.backgroundColor = .white
configuringBottomButton()
configuringStepCollectionView()
}
override func viewDidAppear(_ animated: Bool) {
}
Here is where I try to get the nameFied to add the border
override func viewDidLayoutSubviews() {
NameStepCell().self.nameField.addBottomBorder()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 1 {
let genderCell = collectionView.dequeueReusableCell(withReuseIdentifier: "genderStepId", for: indexPath)
return genderCell
}else if indexPath.item == 2{
let birthdayCell = collectionView.dequeueReusableCell(withReuseIdentifier: "birthdayStepId", for: indexPath)
return birthdayCell
}else if indexPath.item == 3{
let emailCell = collectionView.dequeueReusableCell(withReuseIdentifier: "emailStepId", for: indexPath)
return emailCell
}else if indexPath.item == 4{
let passwordCell = collectionView.dequeueReusableCell(withReuseIdentifier: "passwordStepId", for: indexPath)
return passwordCell
}
let nameCell = collectionView.dequeueReusableCell(withReuseIdentifier: "nameStepId", for: indexPath)
return nameCell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: stepsCollectionView.frame.size.width, height: stepsCollectionView.frame.size.height)
}
}
Extension to textfield to add the bottom border
extension UITextField {
func addBottomBorder() {
let border = CALayer()
border.frame = CGRect(x: 0, y: 32, width: self.frame.size.width, height: 1)
border.cornerRadius = 2
border.masksToBounds = true
border.backgroundColor = UIColor.init(red: 112/255, green: 112/255, blue: 112/255, alpha: 1).cgColor
self.layer.masksToBounds = true
self.layer.addSublayer(border)
}
}
Instead of calling addBottomBar() inside viewDidLayoutSubviews, you can try something like this.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 1 {
let genderCell = collectionView.dequeueReusableCell(withReuseIdentifier: "genderStepId", for: indexPath)
return genderCell
}else if indexPath.item == 2{
let birthdayCell = collectionView.dequeueReusableCell(withReuseIdentifier: "birthdayStepId", for: indexPath)
return birthdayCell
}else if indexPath.item == 3{
let emailCell = collectionView.dequeueReusableCell(withReuseIdentifier: "emailStepId", for: indexPath)
return emailCell
}else if indexPath.item == 4{
let passwordCell = collectionView.dequeueReusableCell(withReuseIdentifier: "passwordStepId", for: indexPath)
return passwordCell
}
// Dequeue your NameStepCell from collection view
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "nameStepId", for: indexPath)
if let nameCell = cell as? NameStepCell {
// Add bottom border to it right here and return it
nameCell.nameField.addBottomBorder()
return nameCell
}
return cell
}
Edit:
Now you don't need to change anything in your SignUpViewController. Please replace your NameStepCell class with the below code.
class NameStepCell: UICollectionViewCell {
var safeAreaHolder: UIView!
var title: UILabel!
var txtFieldStack: UIStackView!
var nameField: UITextField!
var lastNameField: UITextField!
override init(frame: CGRect) {
super.init(frame: frame)
configuringView()
configuringTitle()
configuringTxtField()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
private extension NameStepCell {
func configuringView(){
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
self.safeAreaHolder = view
addSubview(safeAreaHolder)
safeAreaHolder.topAnchor.constraint(equalTo: topAnchor).isActive = true
safeAreaHolder.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16).isActive = true
safeAreaHolder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
safeAreaHolder.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true
self.safeAreaHolder.layoutIfNeeded()
}
func configuringTitle(){
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = UIFont.boldSystemFont(ofSize: 40)
label.text = "What is\nyour\nname?"
self.title = label
safeAreaHolder.addSubview(title)
title.topAnchor.constraint(equalTo: safeAreaHolder.topAnchor, constant: 50).isActive = true
title.trailingAnchor.constraint(equalTo: safeAreaHolder.trailingAnchor).isActive = true
title.leadingAnchor.constraint(equalTo: safeAreaHolder.leadingAnchor).isActive = true
self.title.layoutIfNeeded()
}
func configuringTxtField(){
let stack = UIStackView()
stack.backgroundColor = .lightGray
stack.translatesAutoresizingMaskIntoConstraints = false
stack.alignment = .center
stack.axis = .horizontal
stack.distribution = .fillEqually
stack.spacing = 20
self.txtFieldStack = stack
safeAreaHolder.addSubview(txtFieldStack)
txtFieldStack.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 50).isActive = true
txtFieldStack.trailingAnchor.constraint(equalTo: safeAreaHolder.trailingAnchor).isActive = true
txtFieldStack.leadingAnchor.constraint(equalTo: safeAreaHolder.leadingAnchor).isActive = true
self.txtFieldStack.layoutIfNeeded()
self.nameField = getTextField(.name)
self.lastNameField = getTextField(.familyName)
txtFieldStack.addArrangedSubview(nameField)
txtFieldStack.addArrangedSubview(lastNameField)
nameField.heightAnchor.constraint(equalToConstant: 45).isActive = true
lastNameField.heightAnchor.constraint(equalToConstant: 45).isActive = true
// After adding constraints, you should call 'layoutIfNeeded()' which recomputes the size and position based on the constraints you've set
self.nameField.layoutIfNeeded()
self.lastNameField.layoutIfNeeded()
self.nameField.addBottomBorder()
self.lastNameField.addBottomBorder()
}
func getTextField(_ textContentType: UITextContentType) -> UITextField {
let textField = UITextField()
textField.keyboardType = .default
textField.textContentType = textContentType
textField.autocapitalizationType = .words
textField.autocorrectionType = .no
textField.textColor = .black
textField.placeholder = textContentType.rawValue // P.S. Remove placeholder if you don't need.
return textField
}
}
I am trying to laod an array of images to a collectionview that is within a UIViewController. The UIImageView within my custom UICollectionViewCell is not extending to the bounds of the cell and I do not understand why. Below is my code.
ViewController:
var dragCollectionView: UICollectionView!
var dragCollectionViewWidth: CGFloat!
let borderInset: CGFloat = 3
var interCellSpacing: CGFloat = 3
var spacingBetweenRows: CGFloat = 3
let container1: UIView = {
let v = UIView()
v.backgroundColor = UIColor.yellow
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
margins = view.layoutMarginsGuide
view.backgroundColor = UIColor.white
view.addSubview(container1)
container1.translatesAutoresizingMaskIntoConstraints = false
container1.heightAnchor.constraint(equalTo: margins.heightAnchor, multiplier: 0.5).isActive = true
container1.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
container1.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
container1.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
setUpCollectionViewForPuzzlePieces()
}
override func viewDidLayoutSubviews() {
print("")
print("viewDidLayoutSubviews ...")
dragCollectionViewWidth = dragCollectionView.frame.width
dragCollectionView.translatesAutoresizingMaskIntoConstraints = false
dragCollectionView.topAnchor.constraint(equalTo: container1.topAnchor).isActive = true
dragCollectionView.bottomAnchor.constraint(equalTo: container1.bottomAnchor).isActive = true
dragCollectionView.leftAnchor.constraint(equalTo: container1.leftAnchor).isActive = true
dragCollectionView.rightAnchor.constraint(equalTo: container1.rightAnchor).isActive = true
setupLayoutDragCollectionView()
}
private func setUpCollectionViewForPuzzlePieces(){
let frame = CGRect.init(x: 0, y: 0, width: 100, height: 100)
layout = UICollectionViewFlowLayout.init()
dragCollectionView = UICollectionView.init(frame: frame, collectionViewLayout: layout)
dragCollectionView.backgroundColor = UIColor.gray
dragCollectionView.delegate = self
dragCollectionView.dataSource = self
container1.addSubview(dragCollectionView)
dragCollectionView.translatesAutoresizingMaskIntoConstraints = false
dragCollectionView.topAnchor.constraint(equalTo: container1.topAnchor).isActive = true
dragCollectionView.bottomAnchor.constraint(equalTo: container1.bottomAnchor).isActive = true
dragCollectionView.leftAnchor.constraint(equalTo: container1.leftAnchor).isActive = true
dragCollectionView.rightAnchor.constraint(equalTo: container1.rightAnchor).isActive = true
// Register UICollectionViewCell
dragCollectionView.register(GirdyPickCollectionCell.self, forCellWithReuseIdentifier: cellId)
}
private func setupLayoutDragCollectionView(){
layout.minimumInteritemSpacing = interCellSpacing
layout.minimumLineSpacing = spacingBetweenRows
layout.sectionInset = UIEdgeInsets.init(top: borderInset, left: borderInset, bottom: borderInset, right: borderInset)
guard
let collectionViewWidth = dragCollectionViewWidth,
let numRows = numberOfGridColumns else{return}
print("numRows: \(numRows)")
let cellWidth = getCellWidth(numRows: numRows, collectionViewWidth: collectionViewWidth, interCellSpace: interCellSpacing, borderInset: borderInset)
layout.estimatedItemSize = CGSize.init(width: cellWidth, height: cellWidth)
print("margins.layoutFrame.width: \(margins.layoutFrame.width)")
print("collectionViewWidth: \(collectionViewWidth)")
print("cellWidth: \(cellWidth)")
print("")
}
private func getCellWidth(numRows: CGFloat, collectionViewWidth: CGFloat, interCellSpace: CGFloat, borderInset: CGFloat) -> CGFloat{
let numSpacing = numRows - 1
let cellWidth = (collectionViewWidth - interCellSpace * numSpacing - borderInset * 2) / numRows
return cellWidth
}
extension StartGameViewController: UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
guard let data = puzzlePieces else {return 0}
return data.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = dragCollectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! GirdyPickCollectionCell
guard let data = puzzlePieces else {return cell}
cell.imageView.image = data[indexPath.row].image
return cell
}
}
My custom UICollectionViewCell:
class GirdyPickCollectionCell: UICollectionViewCell {
var image: UIImage?
var imageView: UIImageView = {
let imgView = UIImageView()
return imgView
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(imageView)
self.backgroundColor = UIColor.red.withAlphaComponent(0.3)
setUpLayout()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setUpLayout(){
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
imageView.widthAnchor.constraint(equalToConstant: frame.width).isActive = true
imageView.heightAnchor.constraint(equalToConstant: frame.height).isActive = true
}
}
CONSOLE:
viewDidLayoutSubviews ...
numRows: 5.0
margins.layoutFrame.width: 343.0
collectionViewWidth: 100.0
cellWidth: 16.4
viewDidLayoutSubviews ...
numRows: 5.0
margins.layoutFrame.width: 343.0
collectionViewWidth: 343.0
cellWidth: 65.0
What I am currently getting:
Implement UICollectionViewDelegateFlowLayout in your view controller and provide the size in collectionView:layout:sizeForItemAtIndexPath:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let kWhateverHeightYouWant = 100
return CGSize(width: collectionView.bounds.size.width, height: CGFloat(kWhateverHeightYouWant))
}
You can add constraints to Left (or leading), Top, Right (or trailing) and bottom of the imageView.
This will also help you to set padding between the frames if required.
Use this code:
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
imageView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
I think you should set all edges constraints instead of giving width and height,
Try to add constraints like this
private func setUpLayout(){
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
imageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
imageView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
I have a custom cell set up for UICollectionView. I have a Data model that has an image and title.
I can get the image to show in the cell but cant get the table to show
I tried to set up the label programmatically inside the custom cell (in the same way that the image is set up) yet the image shows but label is invisible...
class CustomCell: UICollectionViewCell {
var data: CustomData? {
didSet {
guard let data = data else {return}
bg.image = data.image
titleLabel.text = data.title
}
}
fileprivate var titleLabel : UILabel = {
let label = UILabel()
label.textAlignment = .left
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 1
label.textColor = .black
label.font = UIFont (name: "Helvetica Neue", size: 30)
label.text = "random text"
return label
}()
fileprivate let bg : UIImageView = {
let iv = UIImageView()
iv.image = #imageLiteral(resourceName: "pic1")
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFill
iv.layer.cornerRadius = 12
iv.layer.masksToBounds = true
iv.clipsToBounds = true
return iv
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(titleLabel)
contentView.addSubview(bg)
bg.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
this is how the custom cell is set up and below how cellForItemAt is setup
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
let color = colorList[indexPath.row]
cell.backgroundColor = color
cell.contentView.layer.masksToBounds = true;
cell.layer.cornerRadius = 12
cell.clipsToBounds = true
return cell
}
any ideas where am I going wrong?
added frame as #rmaddy suggested to titleLable
Try
titleLabel.translatesAutoresizingMaskIntoConstraints = false
Didselect function in CollectionView or TableView;
let trial = TrialViewController ()
self.navigationController?.pushViewController (trial, animated: true)
I want to move to the other page, but it does not respond. The same thing is working when I type.
self.present (den, animated: true, completion: nil)
is working when I type.
why pushViewController not working?
Thnx
Seems self.navigationController? is nil
With storyboard:
self.navigationController?.pushViewController (trial, animated: true)
make sure the current vc is embedded inside a navigationController
without storyboard:
inside didFinishLaunchingWithOptions
self.window?.rootViewController = UINavigationController(root:ViewController())
Your current ViewController is not RootViewController.
In AppDelegate,
set this code:
var mainView = UIStoryboard(name:"Main", bundle: nil)
let viewcontroller : UIViewController = mainView.instantiateViewController(withIdentifier: "FirstScreenVC") as! FirstScreenVC
self.window!.rootViewController = viewcontroller
Now run your code,
Because now the current controller is rootViewController.
You should not instantiate a view controller like this TrialViewController ()
Instead, use:
UIStoryboard(name: "SbName", bundle: nil).instantiateViewController(withIdentifier: "VcID") as? TrialViewController
I don't use storyboard. My class is here;
import UIKit
class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
setupViews()
//register collectionview
collectionView.register(AppCell.self, forCellWithReuseIdentifier: cellId)
collectionView.delegate = self
collectionView.dataSource = self
}
let topView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = UIColor.white
return view
}()
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.backgroundColor = UIColor.orange
return cv
}()
lazy var button: UIButton = {
let btn = UIButton(type: .system)
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setTitle("Buton", for: .normal)
btn.backgroundColor = UIColor.orange
btn.addTarget(self, action: #selector(handleButton), for: .touchUpInside)
return btn
}()
#objc func handleButton() {
print(1212)
}
func setupViews() {
view.addSubview(topView)
topView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
topView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
topView.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
topView.heightAnchor.constraint(equalToConstant: 250).isActive = true
view.addSubview(button)
button.topAnchor.constraint(equalTo: topView.topAnchor, constant: 15).isActive = true
button.centerXAnchor.constraint(equalTo: topView.centerXAnchor, constant: 0).isActive = true
button.widthAnchor.constraint(equalToConstant: view.frame.width - 15).isActive = true
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
view.addSubview(collectionView)
collectionView.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 10).isActive = true
collectionView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
collectionView.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
collectionView.heightAnchor.constraint(equalToConstant: view.frame.height).isActive = true
collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! AppCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height * 0.2)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let trial = Trial()
self.navigationController?.pushViewController(trial, animated: true)
}
}
class AppCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame:frame)
backgroundColor = UIColor.purple
setupViews()
}
lazy var button: UIButton = {
let btn = UIButton(type: .system)
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setTitle("Buton", for: .normal)
btn.backgroundColor = UIColor.orange
btn.addTarget(self, action: #selector(handleButton), for: .touchUpInside)
return btn
}()
#objc func handleButton() {
//statusShow.showSettings()
}
func setupViews() {
addSubview(button)
button.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0).isActive = true
button.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0).isActive = true
button.widthAnchor.constraint(equalToConstant: self.frame.width * 0.3).isActive = true
button.heightAnchor.constraint(equalToConstant: self.frame.height * 0.2).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class Trial: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}