sbkl sbkl - 5 months ago 340
Swift Question

Swift - JSQMessagesViewController - cell custom

I understood from this link that you can customise the cell of the JSQMessagesViewController library by overriding this method:

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
//Configure your cell here
return //yourCustomCell
}


Is there a possibility to get a sample code to understand how to implement the actual customisation including the subclass of the JSQMessagesCollectionViewCell?

As an example, I would like to add a label included at the bottom of the message bubble showing the time the message has been sent.

Thank you.

EDIT

I have created a custom cell class as follow:

class MyCustomCell: JSQMessagesCollectionViewCell {

var textLabel: UILabel

override init(frame: CGRect) {

self.textLabel = UILabel(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height/3))
super.init(frame: frame)

self.textLabel.font = UIFont.systemFontOfSize(UIFont.smallSystemFontSize())
self.textLabel.textAlignment = .Center
contentView.addSubview(self.textLabel)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}


The custom cell is made programmatically without any xib file.

So in my JSQMessagesViewController, I have to declare it as follow:

override func viewDidLoad() {

super.viewDidLoad()

self.collectionView!.registerClass(MyCustomCell.self, forCellWithReuseIdentifier: "MyCustomCell")
}


And then, I'm able to override the cellForItemAtIndexPath method as follow:

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCustomCell", forIndexPath: indexPath) as! MyCustomCell
return cell
}


The issue is that I cannot see the messages and previous settings anymore.

What am I doing wrong?

Answer

This is the way I managed to make it:

1- Create two sub-classes:

  • JSQMessagesCollectionViewCellOutgoing

    import UIKit
    import JSQMessagesViewController
    
    class messageViewOutgoing: JSQMessagesCollectionViewCellOutgoing {
    
        @IBOutlet weak var timeLabel: UILabel!
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)        
        }
    }
    
  • JSQMessagesCollectionViewCellIncoming

    import UIKit
    import JSQMessagesViewController
    
    class messageViewIncoming: JSQMessagesCollectionViewCellIncoming {
    
        @IBOutlet weak var timeLabel: UILabel!
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)        
        }
    }
    

2- Create two xib files with names related to the two subclasses above. For each file, add the custom class related in the File's owner Placeholder.

3- Copy/paste the xib templates of each related classes from the JSQMessagesViewController library stored in the Resources folder and add your custom label into it.

4- Link the custom labels to your new subclasses above

5- Override the following function

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let message = self.messages[indexPath.item]

    if message.senderId == self.senderId {

        let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! messageViewOutgoing

        cell.timeLabel.text = localHourFormatter.stringFromDate(message.date)

        return cell

    } else {

        let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! messageViewIncoming

        cell.timeLabel.text = localHourFormatter.stringFromDate(message.date)

        return cell
    }
}

Now the label is displayed in the bubble.

Still some work to do to adapt the size of the bubble for a proper display but this is not the purpose of this question.

Let me know if any comment/question.

Comments