4

I've been trying to diagnose the problem here but I really can't figure out what went wrong. I had a collection view (of messages) showing up fine, until I added an additional collection view in the navigation bar.

This is the setup for the second collection view (the nav bar one):

let navBarCollectionView: UICollectionView = UICollectionView(frame: CGRect(x: CGFloat(70), y: CGFloat(0), width: CGFloat(500), height: CGFloat(40)), collectionViewLayout: UICollectionViewFlowLayout.init())

viewDidLoad:

    // Nav Bar collection view
    let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()
    navBarCollectionView.setCollectionViewLayout(layout, animated: true)
    navBarCollectionView.backgroundColor = UIColor.clear
    navBarCollectionView.register(NavBarCell.self, forCellWithReuseIdentifier: "cell")
    navBarCollectionView.delegate = self
    navBarCollectionView.dataSource = self
    layout.scrollDirection = .horizontal
    self.navigationController?.navigationBar.addSubview(navBarCollectionView)
    navBarCollectionView.reloadData()

Then, all I did was change the collection view methods from

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

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell
    let message = messages[indexPath.item]

    if message.senderId == senderId {
        cell.textView?.textColor = UIColor.white
    } else {
        cell.textView?.textColor = UIColor.black
    }
    return cell
}

to

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    if collectionView == navBarCollectionView {
        return 30
    } else {
        return messages.count
    }
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


    if collectionView == navBarCollectionView {
        let navBarCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)) as! NavBarCell

        navBarCell.avatarImageView.loadImageUsingCacheWithUrlString("https://graph.facebook.com/*removed*/picture?type=large&return_ssl_resources=1")
        navBarCell.avatarImageView.clipsToBounds = true
        navBarCell.avatarImageView.layer.borderWidth = 1.5
        navBarCell.avatarImageView.layer.borderColor = UIColor.getRandomColor().cgColor
        navBarCell.avatarImageView.layer.cornerRadius = 20

        return navBarCell
    } else {
        let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell

        let message = messages[indexPath.item]

        if message.senderId == senderId {
            cell.textView?.textColor = UIColor.white
        } else {
            cell.textView?.textColor = UIColor.black
        }
        return cell
    }
}

In other words, just added some if/else statements to accommodate both collection views. There's also this CV method which is for the JSQMessages framework (in other words does not affect the second collection view, only the messages):

override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {
    return messages[indexPath.item]
}

And I added this one which is necessary for the nav bar collection:

override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: CGFloat(40), height: CGFloat(40))
}

With this code, the navigation bar collection view shows up fine, but the messages are no longer there. With print statements I can see the messages and such do have data, they're just not showing.

If I revert back to using the original collection view methods (the ones without the if/elses), the messages show up fine but obviously the navigation bar collection is no longer there. It's like one or the other.

Can anyone see what's going wrong here? I'm not sure if it's an issue specific with JSQMessages or not. The only thing that seems like could be messing things up is that the messages collection view is just called collectionView, so when I say if collectionView == navBarCollectionView, maybe I'm re-assinging the variable? I really don't know. Here's a screenshot to show what I mean:

enter image description here

Anyway if anyone can see what's causing this, any help will be hugely appreciated! Thanks in advance.

KingTim
  • 1,281
  • 4
  • 21
  • 29
  • Wait--you're adding a collection view to the `navigationBar` *itself*? Are you sure that you don't want to *push* a new collection view controller onto the *`navigationController`*? – NRitH Apr 17 '17 at 15:08
  • Yes, I'm adding the collection view as a subview to the navigation bar (`self.navigationController?.navigationBar.addSubview(navBarCollectionView)`) – KingTim Apr 17 '17 at 15:12
  • Why?! How tall is your navigation bar? If you must add it to the nav bar, you need to set the nav bar's `titleView`, not muck with its view hierarchy the way you would with any other view. – NRitH Apr 17 '17 at 15:14
  • I haven't adjusted the navigation bar's size, so I think default is 40 high? The collection view itself is a row of user avatars like in iMessage, it looks great as it is - except obviously it's at the cost of the messages collection view. I can try a different approach if you think it'll solve the problem, would you mind posting an answer of how to do it your way instead? – KingTim Apr 17 '17 at 15:16
  • In portrait mode, the nav bar's height is 44, and the status bar's height is 20. But if you're going to keep using the collection view in the nav bar, then you should implement a completely separate data source/delegate for it. As you've found, trying to use a single data source/delegate for two completely different collection views is a Bad Thing. – NRitH Apr 17 '17 at 15:19
  • So make a new class with its own collection view methods (and the setup code that I currently have in `viewDidLoad`), then with a reference to the chat controller say `chatVC.navigationController?.navigationBar.addSubview(navBarCollectionView)`? – KingTim Apr 17 '17 at 15:22
  • Yes, create a new class with its own collection view methods. But to *set* the collection view in the nav bar, use `chatVC.navigationItem.titleView = navBarCollectionView`. – NRitH Apr 17 '17 at 15:27
  • https://pastebin.com/7WYaqUvM I tried to set up the new nav bar class (and also restored the collection view methods in the chatVC to normal), and just like before, the messages now show up but the navigation bar CV does not. – KingTim Apr 17 '17 at 15:34
  • @NRitH any idea why the other class isn't working in this case? – KingTim Apr 17 '17 at 19:00

0 Answers0