Вставка одного элемента в коллекцию перезагружает КАЖДЫЙ отдельный элемент внутри CollectionView

#ios #swift #core-data #jsqmessagesviewcontroller

#iOS #swift #core-данные #jsqmessagesviewcontroller

Вопрос:

Я сократил свой код всего до дюжины строк ради этого вопроса. Я связал fetchedResultsController с платформой JSQMessagesViewController.

Что делает приложение, так это то, что когда вы нажимаете кнопку отправки, оно вставляет объект в контекст, который активирует .Insert fetchedResultsController.

По какой-то причине каждый раз, когда я вставляю в представление коллекции, он перезагружает каждую отдельную вещь в представлении коллекции. Это вызывает массу ошибок, и я не могу сказать, что я делаю неправильно, из-за самой платформы JSQ или это нормально?

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

 class ChatController: JSQMessagesViewController, NSFetchedResultsControllerDelegate {

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    lazy var fetchedResultsControler: NSFetchedResultsController<NSFetchRequestResult> = {

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Message")
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
        let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.context, sectionNameKeyPath: nil, cacheName: nil)
        frc.delegate = self
        return frc
    }()

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    if type == .insert {   
            collectionView.insertItems(at: [newIndexPath!])
            scrollToBottom(animated: true)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.senderId = ""
    self.senderDisplayName = ""

    do {   
        try fetchedResultsControler.performFetch()  
    }

    catch { }       
}

override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
    let message = NSEntityDescription.insertNewObject(forEntityName: "Message", into: context) as! Message

    message.text = text
    message.timestamp = Date() as NSDate?      
}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {
    let msg : Message = fetchedResultsControler.object(at: indexPath) as! Message
    let messageData = JSQMessage(senderId: senderId, displayName: senderDisplayName, text: msg.text)
    return messageData
}


override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return (fetchedResultsControler.sections?[0].numberOfObjects)!
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell
    cell.layer.shouldRasterize = true
    cell.layer.rasterizationScale = UIScreen.main.scale
    return cell
}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {
    let bubbleFactory = JSQMessagesBubbleImageFactory()
    return bubbleFactory?.outgoingMessagesBubbleImage(with: .black)
}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {
    return nil
}

}
  

Комментарии:

1. вы решили это, столкнулись с той же проблемой

Ответ №1:

Я не уверен, но попробуйте, может ли это вам помочь.

 collectionView?.performBatchUpdates({
            self.collectionView?.reloadItems(at: indexPaths)
        }) { completed in
            //Your Completion Code
            }
        }
  

Комментарии:

1. привет, Дипак, моя проблема не в том, что я хочу перезагружать что-то одно за раз. На самом деле, я не хочу ничего перезагружать. Но по какой-то причине вставка элемента в коллекцию перезагружает все остальные элементы в представлении коллекции. Я знаю, что это не то, что должно происходить.