2015-07-09 9 views
6

Jego możliwa logika zmiany kolekcji viewView: attributedTextForCellTopLabelAtIndexPath: metoda delegowania dla znacznika daty wyświetlania nie według indexPath.item% 4 == 0? jak w SOMessaging dzień po dniu? lub cokolwiek?Zmiana logiki znacznika czasowego w JSQMessagesViewController

to kodowanie służy do wyświetlania znacznika czasu.

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

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

    return 0.0f; 
} 

Aktualna istniejąca logika wyświetla taki sam znacznik czasu, który jest duplikowany zgodnie z poniższym opisem.

enter image description here

Odpowiedz

21

Ponieważ każdy obiekt JSQMessage ma właściwość date, można po prostu porównać datę każdej wiadomości do dnia poprzedniego komunikatu.

[thisMessageDate timeIntervalSinceDate:(NSDate *)previousMessageDate] daje różnicę w sekundach. Jeśli różnica jest większa niż, powiedzmy, minuta (lub jakikolwiek przedział czasowy, który chcesz), a następnie wyświetlić znacznik czasu.

To jak ja to robię:

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

A potem po prostu powtórzyć tę logikę, aby upewnić się datowniki ma poprawnych wysokościach

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

miłą odpowiedź. Jedyną rzeczą, która powinna być "if (indexPath.item> 0)" zamiast "if (indexPath.item - 1> 0)" w obu callbackach. Tracisz logikę drugiego elementu w stosunku do pierwszego. – yzucker

1

aby pokazać komórek datownik tylko day by day;

Z odpowiedzią @cerenali możemy mieć problemy z datami, które mają różne dni, ale czasy zamknięcia. Jak:

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

sobie z tym poradzić, i zastąpił logikę wewnątrz if z:

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

i końcowy kod będzie:

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

Uwaga: Używam DateTools w moim projekt.

1

Dzięki, @cerenali za miłą odpowiedź.

W Swift-3, kod @cerenali mogą być napisane w: -

 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 
     } 
Powiązane problemy