How can i working push view controller on swift 5? - swift

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

Related

Adding Leading and Trailing into swift image view

I'm want to add the leading and trailing into Imageview . The Imageview properties pass from collection view cell. I have tried following to add the leading and trailing but still the leading and trilling not added into Imageview .
//imageView.leftAnchor.constraint(equalTo: view.leftAnchor , constant: 10),
//imageView.rightAnchor.constraint(equalTo: view.rightAnchor,constant: 10),
imageView.leadingAnchor.constraint(equalToSystemSpacingAfter: view.leadingAnchor, multiplier: 3),
imageView.trailingAnchor.constraint(equalToSystemSpacingAfter: view.trailingAnchor, multiplier: 10),
Here is the view controller with collection view cell:
class PhotoViewController: UIViewController {
var viewModel : PhotoViewModel
init(viewModel : PhotoViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
private let collectionView: UICollectionView = {
let viewLayout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: viewLayout)
collectionView.backgroundColor = .white
return collectionView
}()
private enum LayoutConstant {
static let spacing: CGFloat = 16.0
static let itemHeight: CGFloat = 230.0
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private var activityIndicator: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView()
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
return activityIndicator
}()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
setupLayouts()
viewModel.fecthPhotoRecord()
collectionView.delegate = self
collectionView.dataSource = self
viewModel.delegate = self
view.backgroundColor = .lightGray
collectionView.reloadData()
}
private func setupViews() {
view.backgroundColor = .white
view.addSubview(collectionView)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(PhotoCollectionViewCell.self, forCellWithReuseIdentifier: PhotoCollectionViewCell.identifier)
}
private func setupLayouts() {
collectionView.translatesAutoresizingMaskIntoConstraints = false
// Layout constraints for `collectionView`
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
collectionView.leftAnchor.constraint(equalTo: view.leftAnchor),
collectionView.rightAnchor.constraint(equalTo: view.rightAnchor)
])
}
}
extension PhotoViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewModel.hits.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PhotoCollectionViewCell.identifier, for: indexPath) as! PhotoCollectionViewCell
let row = indexPath.row
let hits = viewModel.hits[indexPath.row]
cell.configureCell(tagName: hits.tags)
cell.configureImageCell(row: row, viewModel: viewModel)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
let detailVC = PhtotoDetailsViewController()
detailVC.rowSelected = indexPath.row
let navController = UINavigationController(rootViewController: detailVC)
detailVC.photoviewModel = viewModel
// navController.modalPresentationStyle = .fullScreen
present(navController, animated: true, completion: nil)
}
}
extension PhotoViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = itemWidth(for: view.frame.width, spacing: LayoutConstant.spacing)
return CGSize(width: width, height: LayoutConstant.itemHeight)
}
func itemWidth(for width: CGFloat, spacing: CGFloat) -> CGFloat {
let itemsInRow: CGFloat = 2
let totalSpacing: CGFloat = 2 * spacing + (itemsInRow - 1) * spacing
let finalWidth = (width - totalSpacing) / itemsInRow
return floor(finalWidth)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: LayoutConstant.spacing, left: LayoutConstant.spacing, bottom: LayoutConstant.spacing, right: LayoutConstant.spacing)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return LayoutConstant.spacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return LayoutConstant.spacing
}
}
Code in collection view cell .
import UIKit
protocol ReusableView: AnyObject {
static var identifier: String { get }
}
class PhotoCollectionViewCell: UICollectionViewCell {
private enum Constants {
// MARK: contentView layout constants
static let contentViewCornerRadius: CGFloat = 4.0
// MARK: profileImageView layout constants
static let imageHeight: CGFloat = 180.0
// MARK: Generic layout constants
static let verticalSpacing: CGFloat = 8.0
static let horizontalPadding: CGFloat = 16.0
static let profileDescriptionVerticalPadding: CGFloat = 8.0
}
private let imageView: UIImageView = {
let imageView = UIImageView(frame: .zero)
imageView.contentMode = .scaleAspectFill
return imageView
}()
private let tagLabel: UILabel = {
let label = UILabel(frame: .zero)
label.textAlignment = .center
label.numberOfLines = 0
return label
}()
override init(frame: CGRect) {
super.init(frame: .zero)
setupViews()
setupLayouts()
}
private func setupViews() {
contentView.clipsToBounds = true
contentView.layer.cornerRadius = Constants.contentViewCornerRadius
contentView.backgroundColor = .white
contentView.addSubview(imageView)
contentView.addSubview(tagLabel)
}
private func setupLayouts() {
imageView.translatesAutoresizingMaskIntoConstraints = false
tagLabel.translatesAutoresizingMaskIntoConstraints = false
// Layout constraints for `imageView`
NSLayoutConstraint.activate([
imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
imageView.heightAnchor.constraint(equalToConstant: Constants.imageHeight)
])
// Layout constraints for `tagLabel`
NSLayoutConstraint.activate([
tagLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Constants.horizontalPadding),
tagLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -Constants.horizontalPadding),
tagLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: Constants.profileDescriptionVerticalPadding)
])
}
func configureCell(tagName: String) {
tagLabel.text = tagName
}
func configureImageCell(row: Int, viewModel: PhotoViewModel) {
imageView.image = nil
viewModel
.downloadImage(row: row) { [weak self] data in
let image = UIImage(data: data)
self?.imageView.image = image
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension PhotoCollectionViewCell: ReusableView {
static var identifier: String {
return String(describing: self)
}
}
Here is the details view controller:
import UIKit
class PhtotoDetailsViewController: UIViewController {
var photoviewModel : PhotoViewModel?
var peopleDetailsViewModel:PeopleDetailsViewModel?
private let imageView: UIImageView = {
let imageView = UIImageView(frame: .zero)
imageView.contentMode = .scaleAspectFill
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
private let tagLabel: UILabel = {
let label = UILabel(frame: .zero)
label.textAlignment = .center
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(imageView)
view.addSubview(tagLabel)
setUpUI()
setPhoto()
setContrain()
}
private func setContrain(){
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: view.topAnchor,constant: 100),
imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor,constant: -200),
//imageView.leftAnchor.constraint(equalTo: view.leftAnchor , constant: 10),
//imageView.rightAnchor.constraint(equalTo: view.rightAnchor,constant: 10),
imageView.leadingAnchor.constraint(equalToSystemSpacingAfter: view.leadingAnchor, multiplier: 3),
imageView.trailingAnchor.constraint(equalToSystemSpacingAfter: view.trailingAnchor, multiplier: 10),
tagLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor),
tagLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tagLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
private func setUpUI(){
tagLabel.text = photoviewModel?.hits.first?.tags
}
var rowSelected = 0
private func setPhoto(){
photoviewModel?.downloadImage(row: rowSelected) { [weak self] data in
DispatchQueue.main.async {
let image = UIImage(data: data)
self?.imageView.image = image
}
}
}
}
Debugging results in
Here is the screenshot:
Leading added .

Button in custom UICollectionViewCell class does not taking action

Hi I am developing a route finder application, and inside the application when user searches for specific places, app provides number of places on both map and in UICollectionView which contains short description of list of places found and a "Go" UIButton to show the direction. However, despite the fact that button is shown on the cell and is touchable, meaning isUserInteractionEnabled is true, button is not triggering an action. "Pressed" is not shown on console. (Note: Screen shot is available for demonstration purposes.)
Declaration of the UICollectionView in MapViewController.
let collectionViewOfListOfPlaces:UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.register(CustomCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
In viewDidLoad function of MapViewController this lines are added.
collectionViewOfListOfPlaces.reloadData()
collectionViewOfListOfPlaces.delegate = self
In extension of MapViewController this lines functions are added.
func setupCollectionViewOfListOfPlaces(){
hideListViewButton.translatesAutoresizingMaskIntoConstraints = false
hideListViewButton.isUserInteractionEnabled = true
collectionViewOfListOfPlaces.backgroundColor = UIColor.white.withAlphaComponent(0)
collectionViewOfListOfPlaces.topAnchor.constraint(equalTo: listContentView.topAnchor, constant: 0).isActive = true
collectionViewOfListOfPlaces.leadingAnchor.constraint(equalTo: listContentView.leadingAnchor, constant: 10).isActive = true
collectionViewOfListOfPlaces.trailingAnchor.constraint(equalTo: listContentView.trailingAnchor, constant: -10).isActive = true
collectionViewOfListOfPlaces.heightAnchor.constraint(equalToConstant: view.frame.height/5).isActive = true // ?
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionViewOfListOfPlaces.frame.height/0.8, height: collectionViewOfListOfPlaces.frame.height/1.2)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return landmarks.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionViewOfListOfPlaces.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
let cellData = self.landmarks[indexPath.item]
cell.backgroundColor = Colors.violet3
cell.setData(dataa: cellData) //????????
cell.delegate = self
return cell
}
Custom class:
import Foundation
import UIKit
protocol CustomCellDelegate {
func didPrintNameOfPlace(placeName: String)
}
class CustomCell: UICollectionViewCell {
// var data: Landmark? {
// didSet {
// guard let data = data else { return }
//
// }
// }
let directButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Go", for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 18)
button.addTarget(
self,
action: #selector(directButtonPressed),
for: UIControl.Event.touchUpInside)
button.backgroundColor = .white
return button
}()
var data: Landmark?
var delegate: CustomCellDelegate?
override init(frame: CGRect) {
super.init(frame: .zero)
setUpDirectButton()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setData(dataa: Landmark){
data = dataa
}
func setUpDirectButton(){
contentView.addSubview(directButton)
directButton.translatesAutoresizingMaskIntoConstraints = false
directButton.isUserInteractionEnabled = true
directButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
directButton.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0).isActive = true
directButton.widthAnchor.constraint(equalToConstant: 50).isActive = true
directButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
directButton.frame.size.width = 50
directButton.frame.size.height = 50
}
#objc func directButtonPressed(sender: UIButton!) {
// delegate?.didPrintNameOfPlace(placeName: data!.nameOfPlace)
print("Pressed")
}
}
```[Screen shot link][1]
[1]: https://i.stack.imgur.com/azHSd.jpg
Mark your button initialise with lazy
private lazy var directButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Go", for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 18)
button.addTarget(
self,
action: #selector(directButtonPressed),
for: UIControl.Event.touchUpInside)
button.backgroundColor = .white
return button
}()
Cut this line:
button.addTarget(
self,
action: #selector(directButtonPressed),
for: UIControl.Event.touchUpInside)
...and paste it inside setupDirectButton. Your button will start working.

How do I access content of a uicollectionviewcell in a view controller?

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

to dismiss a viewcontroller using collectionView cell

i am having a difficulty on dismissing a viewController when i click a collectionviewcell. so my collectionview is placed inside a uiview that is then displayed in a viewcontroller. whenever the user click on collectionViewCell, i want the view to trigger bye() function that is placed inside the viewcontroller. i add print("bye") just to see if it work, and it does print the word but it does not execute dismiss(animated: true, completion: nil) to dismiss the viewcontroller along with the uiview and collectionview. why it does not dismiss the controller? is there another way that i can do the same thing? here is the code :
the view controller
class sideViewController: UIViewController {
let dismissBtn:UIButton = {
let content = UIButton()
content.backgroundColor = .green
content.addTarget(self, action: #selector(bye), for: .touchUpInside)
return content
}()
let sideTableViews: sideCollectionView = {
let content = sideCollectionView()
return content
}()
override func viewDidLoad() {
super.viewDidLoad()
dismissBtn.translatesAutoresizingMaskIntoConstraints = false
sideTableViews.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(dismissBtn)
view.addSubview(sideTableViews)
dismissBtn.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
dismissBtn.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10).isActive = true
dismissBtn.widthAnchor.constraint(equalToConstant:40).isActive = true
dismissBtn.heightAnchor.constraint(equalToConstant: 40).isActive = true
sideTableViews.topAnchor.constraint(equalTo: dismissBtn.bottomAnchor, constant: 30).isActive = true
sideTableViews.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
sideTableViews.widthAnchor.constraint(equalTo: view.widthAnchor, constant: 0).isActive = true
sideTableViews.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func membershipController(){
let next = self.storyboard?.instantiateViewController(withIdentifier: "membershipViewController") as! membershipViewController
self.present(next, animated: true, completion: nil)
}
#objc func bye(){
print("bye")
dismiss(animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
this is the collectionView code and the uiview
class sideCollectionView:UIView, UICollectionViewDelegateFlowLayout,UICollectionViewDataSource {
let arrayLbl = ["connection","achievement","template","setting"]
let arrayImg = ["connection","achievement","template","setting"]
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrayLbl.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! sideCollectionViewCell
cell.titleImg.image = UIImage(named: "\(arrayImg[indexPath.row])")
cell.titleLbl.text = arrayLbl[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (self.frame.width / 2) - 40, height: (self.frame.width / 2) - 40)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(25, 25, 10, 25)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.row == 0{
connectController()
print("connection")
let side = sideViewController()
side.bye()
}
if indexPath.row == 1{
let side = sideViewController()
side.bye()
print("achievement")
}
if indexPath.row == 2{
let side = sideViewController()
side.bye()
print("template")
}
if indexPath.row == 3{
let side = sideViewController()
side.bye()
print("setting")
}
}
lazy var collectionViews: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.clear
cv.dataSource = self
cv.delegate = self
return cv
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
func setupViews(){
collectionViews.register(sideCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
collectionViews.translatesAutoresizingMaskIntoConstraints = false
backgroundColor = UIColor.clear
addSubview(collectionViews)
collectionViews.topAnchor.constraint(equalTo: topAnchor, constant: 0).isActive = true
collectionViews.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0).isActive = true
collectionViews.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
collectionViews.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0).isActive = true
collectionViews.widthAnchor.constraint(equalTo: widthAnchor, constant: 0).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
#objc func connectController(){
let side = sideViewController()
side.bye()
}
#objc func settingController(){
let side = sideViewController()
side.bye()
}
#objc func achievementController(){
let side = sideViewController()
side.bye()
}
#objc func templateController(){
let side = sideViewController()
side.bye()
}
}
Because this
let side = sideViewController()
is another instance other than the displayed one , so add this var to the view
class sideCollectionView:UIView {
var currentVc:sideViewController?
}
//
when you create the variable assign it
lazy var sideTableViews: sideCollectionView = {
let content = sideCollectionView()
content.currentVc = self
return content
}()
//
Inside
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.row == 0{
connectController()
print("connection")
currentVc?.bye()
}
}

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).
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
}()