更改 JSQMessagesViewController 中的时间戳逻辑

Change a timestamp logic in JSQMessagesViewController

collectionView 的可能变化逻辑:attributedTextForCellTopLabelAtIndexPath: 显示日期时间戳的委托方法不是 indexPath.item % 4 == 0?每天在 SOMessaging 中感觉如何?或者什么?

此编码用于显示时间戳。

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

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

    return 0.0f;
}

当前存在的逻辑显示相同的时间戳被复制如下。

因为每个 JSQMessage 对象都有一个 date 属性,您可以简单地将每条消息的日期与前一条消息的日期进行比较。

[thisMessageDate timeIntervalSinceDate:(NSDate *)previousMessageDate] 会以秒为单位告诉您差异。如果差异大于一分钟(或您想要的任何时间间隔),则显示时间戳。

我就是这样做的:

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

然后重复此逻辑以确保时间戳具有正确的高度:

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

仅显示时间戳单元格day by day

根据 @cerenali 的回答,我们可能会遇到日期不同但关闭时间不同的问题。喜欢:

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

为了处理这个问题,我将 if 中的逻辑替换为:

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

最终代码为:

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

注意:我在我的项目中使用 DateTools

谢谢@cerenali 的精彩回答。

Swift-3中,@cerenali代码可以写成:-

     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
        }