6

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

当前现有逻辑显示相同的时间戳,如下所示。

在此处输入图像描述

4

3 回答 3

22

因为每个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;
}
于 2015-07-30T23:50:37.773 回答
1

仅显示时间戳单元格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

于 2016-02-29T15:57:41.627 回答
1

谢谢,@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
        }
于 2017-09-18T12:38:10.687 回答