Two CollectionViews in One Viewcontroller

I´m trying to put two CollectionViews in one Viewcontroller. I have tried many solutions, but every time the data only shows in the first CollectionsView. The data I want to put in both CollectionView is the same.

How do I do this

My code

import UIKit
import Firebase
import MobileCoreServices
import AVKit

private let reuseIdentifier = "Cell"

var databaseRefRoom: FIRDatabaseReference {
    return FIRDatabase.database().reference()
    }

class RoomViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITableViewDelegate {

    //ScrollView
    @IBOutlet weak var favoritesBtn: UIButton!
    @IBOutlet weak var yourChatBtn: UIButton!
    @IBOutlet weak var mostPopularBtn: UIButton!

    //RoomCollectionView -> RoomViewCollectionViewCell
    var rooms = [Room]()
    @IBOutlet weak var collectionView: UICollectionView!



    //RoomViewController material
    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "Chuloo"

        self.navigationController?.isNavigationBarHidden = false

        favoritesBtn.setTitle("Favorites", for:.normal)
        favoritesBtn.titleLabel?.textColor = UIColor.white
        favoritesBtn.titleLabel?.font = UIFont(name: "AppleSDGothicNeo-Bold", size: 14)
        favoritesBtn.backgroundColor = UIColor.orange

        yourChatBtn.setTitle("Your Chat", for:.normal)
        yourChatBtn.titleLabel?.textColor = UIColor.white
        yourChatBtn.titleLabel?.font = UIFont(name: "AppleSDGothicNeo-Bold", size: 14)
        yourChatBtn.backgroundColor = UIColor.red

        mostPopularBtn.setTitle("Most Popular", for:.normal)
        mostPopularBtn.titleLabel?.textColor = UIColor.white
        mostPopularBtn.titleLabel?.font = UIFont(name: "AppleSDGothicNeo-Bold", size: 14)
        mostPopularBtn.backgroundColor = UIColor.blue


        //RoomCollectionView -> Display CollectionView i ScrollView -> Extension
        collectionView.dataSource = self
        collectionView.delegate = self

        let date = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "dd.MMMM.yyyy - hh:mm:ss a"
        formatter.amSymbol = "AM"
        formatter.pmSymbol = "PM"
        let result = formatter.string(from: date)

        //Hide backButton
        self.navigationItem.setHidesBackButton(true, animated: false)

        //RoomCollectionView -> DataService fetch from Server
        DataService.dataService.fetchDataFromServer { (room) in
            self.rooms.append(room)
            let indexPath = IndexPath(item: self.rooms.count - 1, section: 0)
            self.collectionView?.insertItems(at: [indexPath])
            }

        //Online User Status
        let usersRef = databaseRefRoom.child("online")
        let currentUserRef = usersRef.child((FIRAuth.auth()?.currentUser?.displayName)!)
        currentUserRef.setValue("online")
        currentUserRef.onDisconnectRemoveValue()

        //Database User child Online Status
        let usersRefUser = databaseRefRoom.child("users").child((FIRAuth.auth()?.currentUser?.displayName)!).child("Online Status").child("online")
        usersRefUser.setValue(result)

        let usersRefOffline = databaseRefRoom.child("users").child((FIRAuth.auth()?.currentUser?.displayName)!).child("Online Status")
        usersRefOffline.onDisconnectUpdateChildValues(["offline": result])


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }
}

//RoomCollectionView -> Display
extension RoomViewController {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return rooms.count

    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "roomCell", for: indexPath) as! RoomViewCollectionViewCell

        let room = rooms[indexPath.row]

        cell.layer.cornerRadius = 4
        cell.layer.borderColor = UIColor(red: 248.0/255.0, green: 248.0/255.0, blue: 248.0/255.0, alpha:  1.0).cgColor
        cell.layer.borderWidth = 1
        cell.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
        cell.layer.shadowOffset = CGSize(width: 0, height: 2)
        cell.layer.shadowOpacity = 0.5
        cell.layer.shadowRadius = 1.0
        cell.layer.masksToBounds = false

        // Configure the cell
        cell.configureCell(room: room)
        return cell
    }

    func collectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, sizeForItemAt: IndexPath) -> CGSize {
        return  CGSize(width: view.frame.width / 2 - 5, height: view.frame.width / 2 - 5)

    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    }


}

Upvotes: 0

Views: 1801

Answers (1)

Ahmad F
Ahmad F

Reputation: 31645

Let's walk through what is the problem of your code and how you could solve it.

First:

You mentioned that:

I´m trying to put two CollectionViews in one Viewcontroller.

but your code doesn't seems to be containing two collection views. So what you should do is:

class ViewController: UIViewController {
    .
    .
    .

    @IBOutlet weak var collectionView1: UICollectionView!
    @IBOutlet weak var collectionView2: UICollectionView!

    .
    .
    .
}

Make sure that you are connecting both of collection views to the view controller.

Second:

I have tried many solutions, but every time the data only shows in the first CollectionsView. The data I want to put in both CollectionView is the same.

Make sure -after implementing the first step- is to conform to both collection views dataSource and delegate:

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    .
    .
    .

    @IBOutlet weak var collectionView1: UICollectionView!
    @IBOutlet weak var collectionView2: UICollectionView!

    override func viewDidLoad() {
        .
        .
        .

        collectionView1.dataSource = self
        collectionView1.delegate = self
        collectionView2.dataSource = self
        collectionView2.delegate = self

        .
        .
        .
    }

    .
    .
    .
}

That's should leads to achieve requirement of "I want to put in both CollectionView is the same".

Also

What if you need to let each of the collection view to read from a different data source? you could let the dateSource/delegate method to recognize the collection view by setting a tag it, as follows:

In viewDidLoad() method:

// setting tags:
collectionView1.tag = 101
collectionView2.tag = 102

Thus:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return collectionView === collectionView1 ? dataSource1.count : dataSource2.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellID", for: indexPath)

    let currentObject = collectionView === collectionView1 ? dataSource1[indexPath.row] : dataSource2[indexPath.row]

    .
    .
    .

    return cell
}

And so on...

Hope this helped.

Upvotes: 3

Related Questions