Change timestamp logic in JSQMessagesViewController

Its possible logic of change is collectionView: attributedTextForCellTopLabelAtIndexPath: delegation method for date stamp date not according to indexPath.item% 4 == 0? how like in somessaging day after day? or something else?

this encoding is intended to display a timestamp.

- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.item % 3 == 0) { return kJSQMessagesCollectionViewCellLabelHeightDefault; } return 0.0f; } 

Current existing logic displays the same timestamp as shown below.

enter image description here

+6
source share
3 answers

Since each JSQMessage object has a date property, you can simply compare the date of each message with the date of the previous message.

[thisMessageDate timeIntervalSinceDate:(NSDate *)previousMessageDate] will give you the difference in seconds. If the difference is greater than, say, a minute (or any other time interval you wish), then display the timestamp.

Here is how I do it:

 - (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath { JSQMessage *message = [self.messages objectAtIndex:indexPath.item]; if (indexPath.item == 0) { return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date]; } if (indexPath.item - 1 > 0) { JSQMessage *previousMessage = [self.messages objectAtIndex:indexPath.item - 1]; if ([message.date timeIntervalSinceDate:previousMessage.date] / 60 > 1) { return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date]; } } return nil; } 

And then just repeat this logic to make sure the timestamps are at the correct height:

 - (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.item == 0) { return kJSQMessagesCollectionViewCellLabelHeightDefault; } if (indexPath.item - 1 > 0) { JSQMessage *previousMessage = [self.messages objectAtIndex:indexPath.item - 1]; JSQMessage *message = [self.messages objectAtIndex:indexPath.item]; if ([message.date timeIntervalSinceDate:previousMessage.date] / 60 > 1) { return kJSQMessagesCollectionViewCellLabelHeightDefault; } } return 0.0f; } 
+22
source

Show only temporary cell day by day ;

With @cerenali answer, we may have problems with dates that have different days but are close. How:

 msgDate1 = 31/03/2016 23:55 msgDate2 = 01/04/2016 00:07 

to handle this, I replaced the logic inside the if with:

 BOOL checkTime = message.date.year != previousMessage.date.year || message.date.month != previousMessage.date.month || message.date.day != previousMessage.date.day; 

and the final code will be:

  JSQMessage *message = [self.messages objectAtIndex:indexPath.item]; if (indexPath.item == 0) { return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date]; } if (indexPath.item - 1 > -1) { JSQMessage *previousMessage = [self.messages objectAtIndex:indexPath.item - 1]; BOOL checkTime = message.date.year != previousMessage.date.year || message.date.month != previousMessage.date.month || message.date.day != previousMessage.date.day; if (checkTime) { return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date]; } } 

Note. I am using DateTools in my project.

+1
source

Thanks @cerenali for the good answer.

In Swift-3, @cerenali code can be written to: -

  override func collectionView(_ collectionView: JSQMessagesCollectionView, attributedTextForCellTopLabelAt indexPath: IndexPath) -> NSAttributedString? { let message = self.messages[indexPath.item] if indexPath.item == 0 { return JSQMessagesTimestampFormatter.shared().attributedTimestamp(for: message.date) } if indexPath.item - 1 > 0{ let previousMessage = self.messages[indexPath.item - 1 ] if ( ( message.date.timeIntervalSince(previousMessage.date) / 60 ) > 1){ return JSQMessagesTimestampFormatter.shared().attributedTimestamp(for: message.date) } } return nil } override func collectionView(_ collectionView: JSQMessagesCollectionView, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout, heightForCellTopLabelAt indexPath: IndexPath) -> CGFloat { if indexPath.item == 0 { return kJSQMessagesCollectionViewCellLabelHeightDefault } if indexPath.item - 1 > 0{ let message = self.messages[indexPath.item] let previousMessage = self.messages[indexPath.item - 1 ] if ( ( message.date.timeIntervalSince(previousMessage.date) / 60 ) > 1){ return kJSQMessagesCollectionViewCellLabelHeightDefault } } return 0.0 } 
+1
source

All Articles