【问题标题】:How to make UICollectionView scroll from bottom for chat application after reload data?重新加载数据后,如何使 UICollectionView 从底部滚动聊天应用程序?
【发布时间】:2019-12-10 22:51:52
【问题描述】:

当用户单击发送消息 UIButton 并且当用户再次打开应用程序时,我想从下到上滚动我的 UICollectionView,最后发送的消息必须首先在底部看到。

我刚刚尝试了所有堆栈溢出答案和其他网站代码,但找不到任何解决我的问题的方法。

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
    }


}

输出

打开聊天应用模块时首先看到的第一个索引路径。

【问题讨论】:

标签: ios swift uicollectionview swift4 uicollectionviewcell


【解决方案1】:

要让collectionView从底部填充,您可以在collectionView重新加载时修改collectionView的顶部插图,

在调用 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)
}

然后在您希望滚动到底部时(在 collectionView 重新加载并更新内容插图后在数据源的 didSet 中),调用:

func scrollToBottom() {

    guard !yourDataSource.isEmpty else { return }

    let lastIndex = yourDataSource.count - 1

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

}

【讨论】:

  • 嗨,kristian H,你的回答是对的,我前天已经这样做了,但是在这我遇到了一个小问题,所以请你进一步帮助我
  • @Meet Soni 你有什么问题?
  • 出了什么问题?
【解决方案2】:

如果你想从底部开始收集视图,你必须旋转 collectionView 和它的单元格。

首先在 ViewdidLoad 中旋转 collectionView

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

比在 cellforitematindexpath 中旋转单元格

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

【讨论】:

  • 感谢您查看我的问题,但在提出问题堆栈溢出之前我已经这样做了,在此我的聊天消息列表和我的收藏视图将被旋转而不是在底部路径设置索引。
  • 我遇到的问题是,当我从上到下滚动表格视图时,列表隐藏在用户键入他/她的消息的输入文本后面
【解决方案3】:

重新加载您的collectionview 后添加以下代码:

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

【讨论】:

  • 感谢您查看我的问题,但我在 viewDidLoad 方法中添加上述代码后没有任何变化
  • 在添加此代码之前,请确保您的 messageList 数组包含值。否则它不会工作。
  • 您在哪个函数中将值获取到数组messageList ??
  • func getMessage(mChatUser: String, mCuruntUser: String) { // 代码 }
  • 然后在该函数中添加我的代码。在您的数组messageList 之后获取值。
【解决方案4】:

您可以将 Vinod Jacob 的答案中给出的 scrollToItem 语法放在里面。 DispatchQueue.main.async { let ipath = IndexPath(row: messageList.count - 1, section: 0) collectionView.scrollToItem(at: ipath, at: .bottom, animated: false) }

【讨论】:

  • 线程 1:EXC_BREAKPOINT (code=1, subcode=0x107e0384c) ,应用程序崩溃
  • 您也可以尝试将索引语法放入 DispatchQueue 'let ipath = IndexPath(row: messageList.count - 1, section: 0)'
  • stackoverflow.com/questions/27277219/… 如果有这部分会有所帮助
  • 感谢您的回复,但使用此stackoverflow.com/questions/27277219/… 我的应用程序崩溃,并且在询问堆栈溢出问题之前我已经尝试过此操作。
  • guard self.messageList?.count &gt; 0 else{ return } 你可以在collectionview重新加载之前使用它。
【解决方案5】:

在 CollectionView 中从 api 加载聊天后使用此代码。

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)
        })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    相关资源
    最近更新 更多