Reputation: 2321
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?
Upvotes: 2
Views: 3948
Reputation: 31
I got error: Can't cast from messageViewOutgoing to JSQMessagesCollectionViewCellIncoming @sbkl. Did you get this error, because we can't cast from parent type to child type?
Upvotes: 0
Reputation: 2321
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.
Upvotes: 6
Reputation: 3395
I believe that you are just not setting the text of you custom cell. I would also guard for safety
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCustomCell", forIndexPath: indexPath) as? MyCustomCell else {
print("Could not get my custom cell")
return UICollectionViewCell()
}
let message = messages[indexPath.row] // or what ever your messages are called
let cell.mainLabel.text = message.text
return cell
}
Upvotes: 0
Reputation: 586
Go to xcode make a new file then choose Cocoa Touch class and in subclass list choose
UICollectionViewCell and put your custom cell name like
customCellUICollectionViewCell.swift
After that go Mainstoryboard and drag a new collection cell to your view
Select your cell and in the right side menu in xcode choose
Show the identity inspector
and in Custom class type your custom class name
customCellUICollectionViewCell.swift
last thing in your collection view
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! customCellUICollectionViewCell
return cell
}
Upvotes: 0