Отметка времени для каждой ячейки в collectionView

У меня есть collectionView чат, и я хочу отображать время для каждого сообщения.

введите здесь описание изображения

Вот функция ячейки dequeueReusable:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCell", for: indexPath) as! ChatMessageCollectionVIewCell
    let message = messagesArray[indexPath.row]

    cell.configure(with: message)



    return cell

}

А вот функция настройки внутри моего файла collectionViewCell, Сообщения: имеет тип NSManagedOBject (основные данные) и имеет 3 свойства: usserMessage, isFromApi и timeDate.

func configure(with message:Messages)
{
    messageOutlet.text = message.userMessage
    viewForMessages.backgroundColor = UIColor.lightGray


    let currentDateTime = Date()
    let formatter = DateFormatter()
    formatter.timeStyle = .short
    formatter.dateStyle = .none


    timeLabel.text = formatter.string(from: currentDateTime)


    if message.isFromApi == true
    {
        viewForMessages.backgroundColor = .lightGray
        trailingConstraint.constant = 40
        leadingConstraint.constant = 10
    }
    else
    {
        viewForMessages.backgroundColor = #colorLiteral(red: 0, green: 0.5898008943, blue: 1, alpha: 1)
        trailingConstraint.constant = 10
        leadingConstraint.constant = 40
    }
}

На данный момент он правильно показывает мне время для первого сообщения, но когда я добавляю другое сообщение через минуту, оно также меняет время для первого сообщения.


person Daniel Ardeleanu    schedule 26.03.2018    source источник


Ответы (2)


Вы получаете дату во время выполнения, поэтому для каждой ячейки будет отображаться только текущее время, скажем, 9:58 в вашем случае. Чтобы избежать этого, вам нужно сохранить время в вашей модели сообщений.

Попробуйте для этого:

Добавьте свойство времени в свою модель, Messages.swift

var timeString: String?

В collectionViewCell.swift обновите функцию configure() следующим образом:

func configure(with message: Messages) {
    messageOutlet.text = message.userMessage
    viewForMessages.backgroundColor = UIColor.lightGray

    // Check whether time is already present in model or you need to set it as current time
    if let time = message.timeString {
        // time is already present in model
        timeLabel.text = time

    } else {
        // time is not present in model, you need to set it with current time
        let currentDateTime = Date()
        let formatter = DateFormatter()
        formatter.timeStyle = .short
        formatter.dateStyle = .none

        let formattedTime = formatter.string(from: currentDateTime)
        message.timeString = formattedTime // Save the time in model, for future use
        timeLabel.text = formattedTime
    }

    if message.isFromApi == true {
        viewForMessages.backgroundColor = .lightGray
        trailingConstraint.constant = 40
        leadingConstraint.constant = 10
    } else {
        viewForMessages.backgroundColor = #colorLiteral(red: 0, green: 0.5898008943, blue: 1, alpha: 1)
        trailingConstraint.constant = 10
        leadingConstraint.constant = 40
    }
}
person Ankit Jayaswal    schedule 26.03.2018
comment
спасибо за ваш ответ, это имеет смысл, только одна проблема, я не могу использовать строку в своем сообщении, потому что мое сообщение имеет тип CoreData, я добавил новое свойство в свои CoreData с именем timeData, которое имеет тип Date, должен ли я изменить его на тип String? - person Daniel Ardeleanu; 26.03.2018
comment
@DanielArdeleanu, не обязательно, вы также можете использовать тип Date - person Ankit Jayaswal; 26.03.2018
comment
@DanielArdeleanu, просто опасение, что если вы возьмете свойство с типом Date, вам нужно создать formatter и вызвать formatter.string(from: currentDateTime) при загрузке ячейки. Но если вы сохраните timeString в строковом формате так же, как вы сохраняете userMessage, вы можете получить прямой доступ, как показано в ответе. - person Ankit Jayaswal; 26.03.2018

let currentDateTime = Date() вызывается каждый раз при рендеринге ячейки.

Вам нужно сохранить время в объекте сообщения при его создании и читать значение для него каждый раз, когда вы вызываете свой метод configure. что-то типа :

let messageDate = message.messageDate
let formatter = DateFormatter()
formatter.timeStyle = .short
formatter.dateStyle = .none


timeLabel.text = formatter.string(from: messageDate)
person Aatish Molasi    schedule 26.03.2018