6

collectionView の可能な変更ロジック: attributedTextForCellTopLabelAtIndexPath: 日付タイムスタンプを表示するためのデリゲート メソッド not by 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]秒単位で違いが得られます。差がたとえば 1 分 (または任意の時間間隔) より大きい場合は、タイムスタンプを表示します。

これが私がやっている方法です:

- (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 に答える