iosxcodejsqmessagesviewcontroller

Change a timestamp logic in JSQMessagesViewController


Its possible change logic of collectionView: attributedTextForCellTopLabelAtIndexPath: delegate method for show date timestamp not by indexPath.item % 4 == 0? how like in SOMessaging day by day? or whatever?

this coding is for displaying timestamp.

- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
                   layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
{

    if (indexPath.item % 3 == 0) {
        return kJSQMessagesCollectionViewCellLabelHeightDefault;
    }

    return 0.0f;
}

Current existing logic is displaying same timestamp is duplicated as follow.

enter image description here


Solution

  • Because each JSQMessage object has a date property, you can simply compare the date of each message to 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 whatever time interval you desire), then display a timestamp.

    This is how I'm doing 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 have the correct heights:

    - (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;
    }