1

I'm trying to add a subview to each cell (message) of my collectionView (JSQMessagesViewController) to display time of my message, something like this:

enter image description here

Here is my code:

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

        let message = messages[indexPath.item]

        let timeLabel = UILabel()
        timeLabel.frame = cell.textView.frame
        timeLabel.text = "abc"
        timeLabel.textColor = .blue

        cell.addSubview(timeLabel)

        if message.senderId == senderId { // 1
            cell.textView?.textColor = UIColor.black // 3
            cell.avatarImageView.image = self.avatars.0.image
            cell.avatarImageView.layer.cornerRadius = cell.avatarImageView.frame.size.height / 2
            cell.avatarImageView.clipsToBounds = true
        } else {

            cell.textView?.textColor = UIColor.black // 2
            cell.avatarImageView.image = self.avatars.1.image
            cell.avatarImageView.layer.cornerRadius = cell.avatarImageView.frame.size.height / 2
            cell.avatarImageView.clipsToBounds = true

        }

        return cell
    }

But it adds me 2 labels:

enter image description here

Why there are 2 labels? And how can I add this label particularly to the bottom-right of my message? Thanks in advance!

aashish tamsya
  • 4,903
  • 3
  • 23
  • 34
coldembrace
  • 549
  • 8
  • 19

2 Answers2

1

Check JSQMessagesCollectionViewCellIncoming.nib and JSQMessagesCollectionViewCellIncoming.nib and adjust the Cell bottom label as per your need to make it look like your design.Adjust Autolayout constraint and done.

enter image description here

Mukesh
  • 3,680
  • 1
  • 15
  • 32
  • could you give me an example please, how should I set my constraints to place this lable at bottom-right of my msg? I've tried a lot but label still at the bottom – coldembrace Jul 13 '17 at 07:59
1

Problem 1

Basically, you are creating every time new instance of label.

let timeLabel = UILabel()
timeLabel.frame = cell.textView.frame
timeLabel.text = "abc"
timeLabel.textColor = .blue

Due to the concept of reuses, the cell will reuse everything for the next time. So when you add the subview of timeLabel for the first time that is ready to reuse for the next time. and you are adding again it let timeLabel = UILabel() while the label already there and you are putting a new instance every time.

Solution 1

You have to add the subview once and reuse it by using the tag.

Declare the let timeLabel :UILabel? at class level means where your all variables are declare and check its reference in the cellForItemAt atIndexPath like

if timeLabel == nil {
    timeLabel = UILabel()
    timeLabel.frame = cell.textView.frame
    timeLabel.text = "abc"
    timeLabel.textColor = .blue
    timeLabel.tag = 766
    cell.addSubview(timeLabel)
}

And last get it with the tag in the cellForItemAt atIndexPath

Problem 2

That is not in the bottom right because after awakeFromNib() in JSQMessagesCollectionViewCell this is not adding means label adds before setupLayout.

Solution 2

A: You have to add the constraint manually.

B: OR you can try by setting the frame at last line before returning cell.

Salman Ghumsani
  • 3,647
  • 2
  • 21
  • 34
  • thanks, due to your answer I understand what's wrong! – coldembrace Jul 13 '17 at 06:37
  • `let label = UILabel(frame: CGRect(x: 40, y: 50, width: 200, height: 20)) label.textAlignment = .center label.textColor = .red label.tag = 200 view.addSubview(label)` in viewDidLoad – coldembrace Jul 14 '17 at 14:39
  • `override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell let timeLabel: UILabel = view.viewWithTag(200) as! UILabel let message = messages[indexPath.item] let messageTime = self.messagesTime[indexPath.item] timeLabel.text = messageTime }` but it adds only 1 label at the top of my VC. If I add subview at cellForItemAt same result. What I'm doing wrong? – coldembrace Jul 14 '17 at 14:42
  • thx, but this code crashes: http://imgur.com/a/RZNMm http://imgur.com/a/xsX7h http://imgur.com/a/O8UZF http://imgur.com/a/sdw5r – coldembrace Jul 14 '17 at 17:03
  • but I don't open any urls, I just create label, and data which I get from parsing json is 100% correct... – coldembrace Jul 14 '17 at 17:38
  • that is for different post – Salman Ghumsani Jul 14 '17 at 17:40
  • 1
    So you have add this label in the cell class – Salman Ghumsani Jul 14 '17 at 18:06
  • 1
    I can share you the cell class with your modifications but monday if u can that is good – Salman Ghumsani Jul 14 '17 at 18:07
  • Wiill be great, I'll try to do it by myself tomorrow, but it'd be nice to recheck my code with yours, thanks in advance) – coldembrace Jul 14 '17 at 18:15
  • I've made something like what I want but it still not perfect. It'd be great to see your example) – coldembrace Jul 22 '17 at 12:23
  • @SalmanGhumsani hii need help i need to show top label date only once for particular message not for all messages how will i do that – Dilip Tiwari Jul 31 '18 at 13:01
  • @DilipTiwari use section of a table it will work for you! – Salman Ghumsani Jul 31 '18 at 13:04