Meet Soni
Meet Soni

Reputation: 25

How to make UICollectionView scroll from bottom for chat application after reload data?

I want to scroll my UICollectionView from bottom to top when user click on send message UIButton and when user open the app again the last message sent have to seen first at bottom end.

I just tried all stack overflow answers and other sites code also but can't find any solution to my problem.

enter image description here

import UIKit
import Kingfisher
import Firebase
import IQKeyboardManagerSwift

class FireStoreChatViewController: UIViewController, UITextViewDelegate,UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
    @IBOutlet var collectionView: UICollectionView!
    @IBOutlet weak var sendMessageBtn: UIButton!

    var comeFrom : String = ""
    var mChatUser : String = ""
    var mChatUserName : String = ""
    var mCurruntUserId : String = ""
    var isFirstPageFirstLoad: Bool = false
    var lastVisible: DocumentSnapshot? = nil
    var messageList: [Messages] = []

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        self.messageList.reverse()
        return messageList.count
    }


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
       if messageList[indexPath.row].from == mCurruntUserId
       {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Message", for: indexPath as IndexPath) as! MessageCollectionViewCell

       }

      return cell
    }

    @IBAction func sendMessageAction(_ sender: UIButton)
    {
        sendMessage()
    }

    func getMessage(mChatUser: String, mCurruntUser: String)
    { 
       // code
    }

    func sendMessage()
    {
       // code
    }

    func updateChatListData()
    {
       // code
    }


}

Output

First index path seen first while open chat app module.

Upvotes: 1

Views: 4181

Answers (5)

Talha Ahmed
Talha Ahmed

Reputation: 158

use this code after loading the Chat from api in CollectionView.

DispatchQueue.main.async(execute: {

            self.mycollectionView.reloadData()
            self.scrollToBottom()
            //self.table1.setContentOffset(CGPoint(x: 0, y: self.table1.contentSize.height - UIScreen.main.bounds.height), animated: true)
        })

Upvotes: -1

Kristian H
Kristian H

Reputation: 174

To get the collectionView to populate from the bottom, you can modify the top inset of the collection view as the collectionView reloads,

Call this after calling reloadData():

func updateCollectionContentInset() {
    let contentSize = yourCollectionView.collectionViewLayout.collectionViewContentSize
    var contentInsetTop = yourCollectionView.bounds.size.height

        contentInsetTop -= contentSize.height
        if contentInsetTop <= 0 {
            contentInsetTop = 0
    }
    yourCollectionView.contentInset = UIEdgeInsets(top: contentInsetTop,left: 0,bottom: 0,right: 0)
}

Then to scroll to the bottom when you want it to do so (in your data source's didSet after collectionView reload and updating the content inset), call:

func scrollToBottom() {

    guard !yourDataSource.isEmpty else { return }

    let lastIndex = yourDataSource.count - 1

     yourCollectionView.scrollToItem(at: IndexPath(item: lastIndex, section: 0), at: .centeredVertically, animated: true)

}

Upvotes: 4

Tejas Chauhan
Tejas Chauhan

Reputation: 29

You may put scrollToItem syntax given in Vinod Jacob's answer inside. DispatchQueue.main.async { let ipath = IndexPath(row: messageList.count - 1, section: 0) collectionView.scrollToItem(at: ipath, at: .bottom, animated: false) }

Upvotes: 0

Vinu Jacob
Vinu Jacob

Reputation: 381

After reloading your collectionview add the following code:

let ipath = IndexPath(row: messageList.count - 1, section: 0)
collectionView.scrollToItem(at: ipath, at: .bottom, animated: false)

Upvotes: 0

Bhavesh.iosDev
Bhavesh.iosDev

Reputation: 942

if you want start collection view from bottom you have to rotate collectionView and it's cells.

first rotate collectionView in ViewdidLoad

yourCollectionView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(Double.pi)))

than rotate cell in cellforitematindexpath

cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)

Upvotes: -1

Related Questions