CollectionView not registering cells - ios

I have a viewController with a collectionView inside of it. I'm pretty sure that I have configured everything right yet it is not rendering any cells. I have added the appropriate delegates and data sources and double checked to see if the data is loading and it is but cells are not being populated
import UIKit
import UIKit
import Alamofire
import AlamofireNetworkActivityIndicator
import SwiftLocation
import CoreLocation
import AMScrollingNavbar
class NewHomeFeedControllerViewController: UIViewController {
let detailView = EventDetailViewController()
var allEvents = [Event]()
let customCellIdentifier1 = "customCellIdentifier1"
var grideLayout = GridLayout(numberOfColumns: 2)
let refreshControl = UIRefreshControl()
var newHomeFeed: NewHomeFeedControllerViewController?
let paginationHelper = PaginationHelper<Event>(serviceMethod: PostService.showEvent)
lazy var dropDownLauncer : DropDownLauncher = {
let launcer = DropDownLauncher()
launcer.newHomeFeed = self
return launcer
}()
// 1 IGListKit uses IGListCollectionView, which is a subclass of UICollectionView, which patches some functionality and prevents others.
let collectionView: UICollectionView = {
// 2 This starts with a zero-sized rect since the view isn’t created yet. It uses the UICollectionViewFlowLayout just as the ClassicFeedViewController did.
let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout())
// 3 The background color is set to white
view.backgroundColor = UIColor.white
return view
}()
func handleDropDownMenu(){
dropDownLauncer.showDropDown()
}
func configureCollectionView() {
// add pull to refresh
refreshControl.addTarget(self, action: #selector(reloadHomeFeed), for: .valueChanged)
collectionView.addSubview(refreshControl)
}
func reloadHomeFeed() {
self.paginationHelper.reloadData(completion: { [unowned self] (events) in
self.allEvents = events
if self.refreshControl.isRefreshing {
self.refreshControl.endRefreshing()
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
})
}
func categoryFetch(dropDown: DropDown){
navigationItem.title = dropDown.name
paginationHelper.category = dropDown.name
configureCollectionView()
reloadHomeFeed()
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.contentInset = UIEdgeInsetsMake(15, 0, 0, 0)
navigationItem.title = "Home"
collectionView.dataSource = self
collectionView.delegate = self
collectionView.collectionViewLayout = grideLayout
collectionView.reloadData()
collectionView.register(CustomCell.self, forCellWithReuseIdentifier: customCellIdentifier1)
// self.navigationItem.hidesBackButton = true
let backButton = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(handleDropDownMenu))
self.navigationItem.leftBarButtonItem = backButton
configureCollectionView()
reloadHomeFeed()
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navigationController = self.navigationController as? ScrollingNavigationController {
navigationController.followScrollView(self.collectionView, delay: 50.0)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.stopFollowingScrollView()
}
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.showNavbar(animated: true)
}
return true
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
grideLayout.invalidateLayout()
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
extension NewHomeFeedControllerViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allEvents.count
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let customCell = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier1, for: indexPath) as! CustomCell
let imageURL = URL(string: allEvents[indexPath.item].currentEventImage)
print(imageURL ?? "")
customCell.sampleImage.af_setImage(withURL: imageURL!)
return customCell
}
}
extension NewHomeFeedControllerViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.item == 0 || indexPath.item == 1 {
return CGSize(width: view.frame.width, height: grideLayout.itemSize.height)
}else{
return grideLayout.itemSize
}
}
}
Any idea what could be going on?

Sorry you guys forgot to add this
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
Haha thanks for the help

Related

Swift cells are created but don't show up in UICollectionView swift 5

I'm creating a collection view with custom collection view cell. So, I've created the collection view in my storyboard view controller. The problem is that my cells are created in cellForItemAt but they are not shown at all, I've also tried using default cells, but they are not shown either, and of course, I've tried all the solutions I found. Thank you for helping in advance!
view controller class related parts
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
title = set?.name
collectionView!.register(WordCollectionViewCell.self, forCellWithReuseIdentifier: Identifies.WordCollectionViewCellIdentifier)
let buttonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addButtonPressed))
navigationItem.rightBarButtonItem = buttonItem
updateTranslations()
}
hide: false console: true babel: false -->
extension SingleSetViewController : UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print(translations.count)
return translations.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifies.WordCollectionViewCellIdentifier, for: indexPath) as! WordCollectionViewCell
cell.translation = translations[indexPath.row]
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
}
collection view cell class
class WordCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var wordLabel: UILabel!
private var showsWord = true
private var _translation : Translation?
var translation : Translation {
set {
_translation = newValue
}
get {
return _translation ?? Translation(word: "", translation: "")
}
}
override func awakeFromNib() {
super.awakeFromNib()
let gestureRecognizer = UITapGestureRecognizer(target: self , action: #selector(flip))
gestureRecognizer.numberOfTapsRequired = 1
self.addGestureRecognizer(gestureRecognizer)
wordLabel.text = _translation?.word
}
#objc private func flip(_ sender: UIGestureRecognizer){
let options : UIView.AnimationOptions = [.transitionFlipFromRight]
UIView.transition(with: self, duration: 0.5, options: options){
if let translation = self._translation {
self.wordLabel.text = self.showsWord ? translation.translation : translation.word
self.showsWord = !self.showsWord
}
}
}
static func nib() -> UINib {
return UINib(nibName: NibNames.WordCollectionViewCellNibName, bundle: nil)
}
}
your awakeFromNib method is probably firing before your set your cell's translation property. Try setting your label text in your translation's setter:
set {
_translation = newValue
wordLabel?.text = _translation?.word
}

UICollectionView disappear when refreshing after pop back

I have a problem when pull-to-refresh with UICollectionView. The refreshing control work well but when I click on a cell, push another view controller, and pop back, try refreshing, UICollectionView is disappeared( I don't use storyboard).
Screen record video:
https://www.youtube.com/watch?v=3bsaqqv6x_8
Here is my code:
AccountController
class AccountController: UICollectionViewController, UICollectionViewDelegateFlowLayout{
var menuData: [Any]? {
didSet{
self.collectionView?.reloadData()
}
}
let collectionLayout = UICollectionViewFlowLayout()
let refreshControl = UIRefreshControl()
override func viewDidLoad() {
...
setupCollectionView()
self.collectionView?.isHidden = false
refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
collectionView!.addSubview(refreshControl)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
super.collectionViewLayout.invalidateLayout()
}
func setupCollectionView(){
self.collectionView?.isHidden = true
collectionView?.backgroundColor = UIColor(white: 0.95, alpha: 1)
collectionView?.alwaysBounceVertical = true
collectionView?.register(MenuCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.register(MenuSupplementary.self, forCellWithReuseIdentifier: supplementaryId)
collectionLayout.minimumLineSpacing = 0
collectionView?.collectionViewLayout = collectionLayout
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = menuData?.count {
return count
}
return 0
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let dt = menuData?[indexPath.item] {
if dt is MenuCellData{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell
cell.data = dt as? MenuCellData
return cell
}
if dt is MenuSupplementaryData {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: supplementaryId, for: indexPath) as! MenuSupplementary
cell.data = dt as? MenuSupplementaryData
return cell
}
}
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize.init(width: view.frame.width, height: 45)
}
#objc func refresh(sender:UIRefreshControl){
let api = AccountApi(jwt: appDelegate.userDefault.string(forKey: "jwt"))
api.getMenuData { (data) in
var dt: [Any] = []
if data.isEmpty { return }
for d in data as! [MenuData] {
if d.type == "supplementary" {
dt.append(MenuSupplementaryData( d.text ))
}
if d.type == "cell" {
dt.append(MenuCellData(d.icon!, d.text, isTheLastItem: d.isTheLastItem ?? false, url: d.url, httpMethod: d.httpMethod ))
}
}
if !dt.isEmpty {
self.menuData = dt
}
sender.endRefreshing()
}
}
}
TabBarController
class TabBarController: UITabBarController, UITabBarControllerDelegate {
...
private func setUpNavControllerFrom(viewController: UIViewController, title: String, imageName: String)-> UINavigationController{
let navController = UINavigationController(rootViewController: viewController)
navController.tabBarItem.title = title
navController.tabBarItem.image = UIImage(named: imageName)
let imageView = UIImageView.init(frame: CGRect())
imageView.image = UIImage(named: "logo")
imageView.contentMode = .scaleAspectFit
imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true // Set logo height
viewController.navigationItem.titleView = imageView
navController.navigationBar.barTintColor = themeColor
return navController
}
// Set up color, logo, font ...
private func setupViewControllers(){
tabBar.tintColor = UIColor.white
tabBar.barTintColor = themeColor
let accountVC = AccountController(collectionViewLayout: UICollectionViewFlowLayout())
let accNavController = setUpNavControllerFrom(viewController: accountVC, title: "Account", imageName: "account-icon")
...
}
}
Additional info:
Refreshing without pop back: numberOfItemsInSection, cellForItemAt, sizeForItemAt of delegate is invoked when call collectionView?.reloadData().
But, when refreshing after pop back, cellForItemAt, sizeForItemAt of delegate is not invoked when call collectionView?.reloadData().
Thanks for help!
Thanks for trying help me!
I finally find out my mistake.
When handling menu is selected, I create new controller with current collectionViewLayout, and I think this current layout is changed when pop back, make menu is disappeared.
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let dt = menuData?[indexPath.item]{
if dt is MenuCellData {
let d = dt as! MenuCellData
// let controller = AccountMenuController(collectionViewLayout: collectionView.collectionViewLayout)
let controller = AccountMenuController(collectionViewLayout: UICollectionViewLayout())
controller.menuData = d
navigationController?.pushViewController(controller, animated: true)
}
}
}

Function not triggering on scroll

I am trying to trigger a certain function in a collection view when I scroll. Basically Im trying to implement pagination so that when it scrolls to the bottom more items are loaded.
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if indexPath.item >= allEvents.count - 1 {
// print("paginating for post")
paginationHelper.paginate(completion: { [unowned self] (events) in
self.allEvents.append(contentsOf: events)
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
})
}else{
print("Not paginating")
}
}
This is the entire Function
import Foundation
import UIKit
import Alamofire
import AlamofireNetworkActivityIndicator
import SwiftLocation
import CoreLocation
import AMScrollingNavbar
class HomeFeedController: UICollectionViewController, UICollectionViewDelegateFlowLayout,UIGestureRecognizerDelegate {
// let dropDownLauncher = DropDownLauncher()
var isFinishedPaging = false
let detailView = EventDetailViewController()
let refreshControl = UIRefreshControl()
var emptyLabel: UILabel?
var allEvents = [Event]()
//will containt array of event keys
var eventKeys = [String]()
let customCellIdentifier = "customCellIdentifier"
var grideLayout = GridLayout(numberOfColumns: 2)
lazy var dropDownLauncer : DropDownLauncher = {
let launcer = DropDownLauncher()
launcer.homeFeed = self
return launcer
}()
let paginationHelper = PaginationHelper<Event>(serviceMethod: PostService.showEvent)
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.white
collectionView?.collectionViewLayout = grideLayout
collectionView?.reloadData()
self.collectionView?.contentInset = UIEdgeInsetsMake(15, 0, 0, 0)
navigationItem.title = "Home"
collectionView?.register(CustomCell.self, forCellWithReuseIdentifier: customCellIdentifier)
// self.navigationItem.hidesBackButton = true
let backButton = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(handleDropDownMenu))
self.navigationItem.leftBarButtonItem = backButton
// PostService.showEvent(location: User.current.location!) { (event) in
// self.allEvents = event
// print(self.allEvents)
//
// DispatchQueue.main.async {
// self.collectionView?.reloadData()
// }
// }
configureCollectionView()
reloadHomeFeed()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navigationController = self.navigationController as? ScrollingNavigationController {
navigationController.followScrollView(self.collectionView!, delay: 50.0)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.stopFollowingScrollView()
}
}
override func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.showNavbar(animated: true)
}
return true
}
func handleDropDownMenu(){
dropDownLauncer.showDropDown()
}
//will query by selected category
func categoryFetch(dropDown: DropDown){
navigationItem.title = dropDown.name
paginationHelper.category = dropDown.name
configureCollectionView()
reloadHomeFeed()
}
func reloadHomeFeed() {
self.paginationHelper.reloadData(completion: { [unowned self] (events) in
self.allEvents = events
if self.refreshControl.isRefreshing {
self.refreshControl.endRefreshing()
}
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
})
}
func configureCollectionView() {
// add pull to refresh
refreshControl.addTarget(self, action: #selector(reloadHomeFeed), for: .valueChanged)
collectionView?.addSubview(refreshControl)
}
// need to tell it how many cells to have
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allEvents.count
}
// need to tell the collection view controller what type of cell we want to return
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let customCell = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier, for: indexPath) as! CustomCell
let imageURL = URL(string: allEvents[indexPath.item].currentEventImage)
print(imageURL ?? "")
customCell.sampleImage.af_setImage(withURL: imageURL!)
return customCell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//let selectedEvent = self.imageArray[indexPath.row]
//let eventDetailVC
if let cell = collectionView.cellForItem(at: indexPath){
// print("Look here for event name")
// print(detailView.eventName)
detailView.eventKey = allEvents[indexPath.row].key!
detailView.eventPromo = allEvents[indexPath.row].currentEventPromo!
detailView.currentEvent = allEvents[indexPath.row]
present(detailView, animated: true, completion: nil)
//self.navigationController?.pushViewController(detailView, animated: true)
}
print("Cell \(indexPath.row) selected")
}
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if indexPath.item >= allEvents.count - 1 {
// print("paginating for post")
paginationHelper.paginate(completion: { [unowned self] (events) in
self.allEvents.append(contentsOf: events)
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
})
}else{
print("Not paginating")
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
//will make surepictures keep same orientation even if you flip screen
// will most likely lock into portrait mode but still good to have
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
grideLayout.invalidateLayout()
}
//Will allow the first two cells that are displayed to be of varying widths
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.item == 0 || indexPath.item == 1 {
return CGSize(width: view.frame.width, height: grideLayout.itemSize.height)
}else{
return grideLayout.itemSize
}
}
func showLeftView(sender: AnyObject?){
print("Button Pressed")
// sideMenuController?.leftViewController = LeftViewController()
//sideMenuController?.showLeftView(animated: true, completionHandler: nil)
}
}
//responsible for populating each cell with content
class CustomCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
let sampleImage: UIImageView = {
let firstImage = UIImageView()
firstImage.clipsToBounds = true
firstImage.translatesAutoresizingMaskIntoConstraints = false
firstImage.contentMode = .scaleToFill
firstImage.layer.masksToBounds = true
return firstImage
}()
let nameLabel: UILabel = {
let name = UILabel()
name.text = "Custom Text"
name.translatesAutoresizingMaskIntoConstraints = false
return name
}()
func setupViews() {
addSubview(sampleImage)
backgroundColor = UIColor.white
//addSubview(nameLabel)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": sampleImage]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": sampleImage]))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// responsible for creating the grid layout that you see in the home view feed
class GridLayout: UICollectionViewFlowLayout {
var numberOfColumns:Int = 2
init(numberOfColumns: Int) {
super.init()
// controlls spacing inbetween them as well as spacing below them to next item
self.numberOfColumns = numberOfColumns
self.minimumInteritemSpacing = 3
self.minimumLineSpacing = 5
}
// just needs to be here because swift tells us to
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var itemSize: CGSize{
get{
if collectionView != nil {
let collectionVieweWidth = collectionView?.frame.width
let itemWidth = (collectionVieweWidth!/CGFloat(self.numberOfColumns)) - self.minimumInteritemSpacing
let itemHeight: CGFloat = 200
return CGSize(width: itemWidth, height: itemHeight)
}
return CGSize(width: 100, height: 100)
}set{
super.itemSize = newValue
}
}
}
This is the function that is responsible for triggering the event but it seems to go to the else statement literally every time. Any insight would be helpful

UICollection View is not reloading while Navigating back?

I need to reload the collection view while navigating back to that particular view.
I tried implementing all the following things but its not working
1.calling self.collectionView.reloadData() in viewDidAppear()
2.calling self.collectionView.reloadData() in viewWillAppear()
even i tried calling viewDidLoad() in viewDidAppear but yet it is not working.
And checked the other same type of questions but it is not working...
the only way it works is by performing segue action but I dont think so it is efficent can anyone suggest me any idea??
enter code here class RoomDeviceListVC: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout ,segueAction{
let functions = DataFunctionalities()
#IBOutlet weak var collectionView1: UICollectionView!
#IBOutlet weak var collectionView2: UICollectionView!
var horizontalBarLeadingConstraint : NSLayoutConstraint?
static var isVisible : Bool?
static var CollectionViewSection : Int!
static var reloadFlag : Int!
static var delegates : CollectionViewRotation? = nil
var uiFunctions = UIFunctions()
var selectedIndex = IndexPath(item: 0, section: 0)
var constant : CGFloat?
let headerView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
uiFunctions.setViewBackground(view: self.view)
self.navigationItem.hidesBackButton = true
setupHeader()
setupConstraints()
setupHorizontalBar()
collectionView2.clipsToBounds = true
RoomDeviceListVC.CollectionViewSection = selectedIndex.section
BottomViewRoomCell.delegates = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
// self.collectionView2.reloadData()
}
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.collectionView2.reloadData()
RoomDeviceListVC.isVisible = true
}
override func viewDidDisappear(_ animated: Bool) {
RoomDeviceListVC.isVisible = false
}
func setupHorizontalBar(){
let horizontalBar = UIView()
self.view.addSubview(horizontalBar)
horizontalBar.translatesAutoresizingMaskIntoConstraints = false
horizontalBar.backgroundColor = .white
horizontalBarLeadingConstraint = horizontalBar.leadingAnchor.constraint(equalTo: collectionView2.leadingAnchor)
horizontalBarLeadingConstraint?.isActive = true
horizontalBar.heightAnchor.constraint(equalToConstant: 3).isActive = true
NSLayoutConstraint(item: horizontalBar, attribute: .width, relatedBy: .equal, toItem: collectionView1, attribute: .width, multiplier: 0.5, constant: 1).isActive = true
horizontalBar.bottomAnchor.constraint(equalTo: collectionView2.topAnchor).isActive = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let menuName = ["Rooms" , "DeviceList"]
let color :[UIColor] = [.green , .blue]
if collectionView == collectionView1{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MenuBarCell", for: indexPath) as! MenuBarCell
cell.menuLabel.text = menuName[indexPath.section]
cell.menuLabel.textColor = UIColor.darkGray
DispatchQueue.main.async {
self.collectionView1.selectItem(at: self.selectedIndex, animated: false, scrollPosition: .centeredHorizontally)
}
return cell
}
else {
if indexPath.section == 0{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BottomViewRoomCell", for: indexPath) as! BottomViewRoomCell
cell.backgroundColor = .clear
cell.layer.cornerRadius = 9
cell.layer.masksToBounds = true
return cell
}
else{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BottomViewDeviceCell", for: indexPath) as! BottomViewDeviceCell
cell.backgroundColor = .clear
cell.layer.cornerRadius = 9
cell.layer.masksToBounds = true
return cell
}
}
}
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
if collectionView == collectionView1{
return CGSize(width: self.view.frame.width / 2, height: collectionView1.frame.height)
}
else{
return CGSize(width: self.view.frame.width, height: collectionView2.frame.height)
}
}
you may use UINavigationControllerDelegate to handle this situation.
add UINavigationControllerDelegate, sign self to the delegate of your collectionView's navigationController, and then put your personal function inside "willShow/didShow" delegate method. your personal function will be called when you pop back to the collectionView.
some method about cell display is not shown
class HomeCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UINavigationControllerDelegate{
private let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
// sign navigationController's delegate to collectionViewController itself.
navigationController?.delegate = self
}
// push view controller when cell is selected
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let vc = CustomViewController()
navigationController?.pushViewController(vc, animated: true)
}
// call your personal function when this collection view controller shows back
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
if viewController == self {
print("will show self")
}
}
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
if viewController == self {
print("did show self")
}
}
}

create UICollectionViewController subclass and add as a childviewcontroller

I am new to iOS development. I want to create collectionView in two different view controllers with same UI.I want to create only one UICollectionView and resuse it on different view controller instead of create separate collectionViews . On approach i can follow is to create the UICollectionViewController subclass and add this on my viewcontrollers as a childviewcontroller, but not sure if this is the correct approach do not know how addChildViewcontroller works and how to pass data between child and parent viewcontrollers. It would be great if someone can help on this. If any sample code is available to achive this please let me know.
Any help is much appreciated.
You can pass around the same collection view controller instance. Add it in viewWillAppear and remove in viewDidDisappear in first and second classes. Here is a sample code that you could use,
extension UIColor {
class func randomColor() -> UIColor {
let red = CGFloat(arc4random_uniform(255)) / 255.0
let green = CGFloat(arc4random_uniform(255)) / 255.0
let blue = CGFloat(arc4random_uniform(255)) / 255.0
return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
}
class MyCollectionViewController: UICollectionViewController {
let data: [UIColor]
init(data: [UIColor]) {
self.data = data
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSizeMake(100, 100)
layout.scrollDirection = UICollectionViewScrollDirection.Vertical
super.init(collectionViewLayout: layout)
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
cell.backgroundColor = data[indexPath.item]
return cell
}
}
class FirstViewController: UIViewController {
lazy var myData:[UIColor] = {
var allData = [UIColor]()
for i in 0 ..< 20 {
allData.append(UIColor.randomColor())
}
return allData
}()
var collectionViewController: MyCollectionViewController!
override func viewDidLoad() {
super.viewDidLoad()
collectionViewController = MyCollectionViewController(data: self.myData)
let barButton = UIBarButtonItem(title: "Show next", style: .Plain, target: self, action: "showNext:")
navigationItem.rightBarButtonItem = barButton
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let collectionView = collectionViewController.view
collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)
addChildViewController(collectionViewController)
collectionView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
collectionView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
collectionView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
collectionView.rightAnchor.constraintEqualToAnchor(view.rightAnchor).active = true
collectionViewController.didMoveToParentViewController(self)
}
override func viewWillDisappear(animated: Bool) {
super.viewDidDisappear(animated)
collectionViewController.willMoveToParentViewController(nil)
collectionViewController.view.removeFromSuperview()
collectionViewController.removeFromParentViewController()
}
func showNext(sender: AnyObject) {
let secondViewController = SecondViewController(collectionViewController: collectionViewController)
navigationController?.pushViewController(secondViewController, animated: true)
}
}
class SecondViewController: UIViewController {
var collectionViewController: MyCollectionViewController!
init(collectionViewController: MyCollectionViewController) {
self.collectionViewController = collectionViewController
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let collectionView = collectionViewController.view
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
addChildViewController(collectionViewController)
collectionView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
collectionView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
collectionView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
collectionView.rightAnchor.constraintEqualToAnchor(view.rightAnchor).active = true
collectionViewController.didMoveToParentViewController(self)
}
override func viewWillDisappear(animated: Bool) {
super.viewDidDisappear(animated)
collectionViewController.willMoveToParentViewController(nil)
collectionViewController.view.removeFromSuperview()
collectionViewController.removeFromParentViewController()
}
}
I have a Set of Answers you can use,
My source Code is ParentViewController and ChildViewController are
same viewController to be declared.
First you create the ParentViewController and add the
UICollectionView then set the Cell size in ParentViewController.
Second you create UICollectionViewCell in same parentViewController,
then add what u need Label or Buttons to be declare.
In ParentViewController class declare 'UICollectionViewDelegate',
Ex: class MyViewController: UIViewController, UICollectionViewDelegate
Then Create UICollectionViewDelegate methods and i have put my
methods below,
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrayvalue.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("reuseIdentifier", forIndexPath: indexPath)
// Configure the cell
let baseView = cell.viewWithTag(101)
let titleLabel = baseView?.viewWithTag(102) as! UILabel
titleLabel.text = arrayvalue[indexPath.row] as String
return cell
}
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSizeMake(CellSize)
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
collectionView.deselectItemAtIndexPath(indexPath, animated:true)
let storyBoard = UIStoryboard(name: "storyboardName", bundle: nil)
let name: classname = storyBoard.instantiateViewControllerWithIdentifier("reuseIdentifier") as! AnotherViewController
self.navigationController?.pushViewController(name, animated: true)
}
Very Important to give storyboard 'reuseIdentifier' value and also
give inside the class cellForItemAtIndexPath reuseIdentifier, example this line
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("reuseIdentifier", forIndexPath: indexPath)
This code was working for me...

Resources