gpt4 book ai didi

swift - 我的 UICollectionView 使用 Swift 滚动不流畅

转载 作者:行者123 更新时间:2023-11-28 05:54:48 24 4
gpt4 key购买 nike

我有一个 CollectionView,它根据 message 类型(例如,文本、图像)使单元格出队。

我遇到的问题是,当我向上/向下滚动时,滚动非常不稳定,因此用户体验不是很好。这只会在第一次加载单元格时发生,之后滚动很流畅。

有什么办法可以解决这个问题吗?这可能是在显示单元格之前获取数据所花费的时间的问题吗?

我不太熟悉在后台线程等上运行任务,也不确定我可以做哪些更改来完善数据预/获取等。请帮忙!

Gif 在 View 加载时显示向上滚动,它显示单元格/ View 在我尝试向上滚动时不稳定。

enter image description here

这是我的 func loadConversation() 加载 messages 数组

func loadConversation(){

DataService.run.observeUsersMessagesFor(forUserId: chatPartnerId!) { (chatLog) in
self.messages = chatLog
DispatchQueue.main.async {
self.collectionView.reloadData()

if self.messages.count > 0 {
let indexPath = IndexPath(item: self.messages.count - 1, section: 0)

self.collectionView.scrollToItem(at: indexPath, at: .bottom , animated: false)

}
}
}//observeUsersMessagesFor

}//end func

这是我的 cellForItemAt,它使单元格出列

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

let message = messages[indexPath.item]

let uid = Auth.auth().currentUser?.uid


if message.fromId == uid {

if message.imageUrl != nil {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ConversationCellImage", for: indexPath) as! ConversationCellImage
cell.configureCell(message: message)
return cell

} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ConversationCellSender", for: indexPath) as! ConversationCellSender
cell.configureCell(message: message)
return cell

}//end if message.imageUrl != nil


} else {

if message.imageUrl != nil {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ConversationCellImageSender", for: indexPath) as! ConversationCellImageSender
cell.configureCell(message: message)
return cell

} else {

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ConversationCell", for: indexPath) as! ConversationCell
cell.configureCell(message: message)
return cell

}

}//end if uid

}//end func

这是我的 ConversationCell 类,它配置一个自定义单元格以通过 cellForItemAt 出队(注意:此外还有另一个 ConversationCellImage 自定义单元格类,它配置图像消息):

class ConversationCell: UICollectionViewCell {

@IBOutlet weak var chatPartnerProfileImg: CircleImage!
@IBOutlet weak var messageLbl: UILabel!

override func awakeFromNib() {
super.awakeFromNib()


chatPartnerProfileImg.isHidden = false

}//end func

func configureCell(message: Message){

messageLbl.text = message.message

let partnerId = message.chatPartnerId()


DataService.run.getUserInfo(forUserId: partnerId!) { (user) in
let url = URL(string: user.profilePictureURL)
self.chatPartnerProfileImg.sd_setImage(with: url, placeholderImage: #imageLiteral(resourceName: "placeholder"), options: [.continueInBackground, .progressiveDownload], completed: nil)

}//end getUserInfo


}//end func


override func layoutSubviews() {
super.layoutSubviews()

self.layer.cornerRadius = 10.0
self.layer.shadowRadius = 5.0
self.layer.shadowOpacity = 0.3
self.layer.shadowOffset = CGSize(width: 5.0, height: 10.0)
self.clipsToBounds = false

}//end func

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {

//toggles auto-layout
setNeedsLayout()
layoutIfNeeded()

//Tries to fit contentView to the target size in layoutAttributes
let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)

//Update layoutAttributes with height that was just calculated
var frame = layoutAttributes.frame
frame.size.height = ceil(size.height) + 18
layoutAttributes.frame = frame
return layoutAttributes
}

}//end class

时间剖面结果:

enter image description here

编辑:流程布局代码

if let flowLayout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout,
let collectionView = collectionView {
let w = collectionView.frame.width - 40
flowLayout.estimatedItemSize = CGSize(width: w, height: 200)
}// end if-let

编辑:我的自定义单元格类中的preferredLayoutAttributesFitting 函数

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
//toggles auto-layout
setNeedsLayout()
layoutIfNeeded()

//Tries to fit contentView to the target size in layoutAttributes
let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)

//Update layoutAttributes with height that was just calculated
var frame = layoutAttributes.frame
frame.size.height = ceil(size.height) + 18
layoutAttributes.frame = frame
return layoutAttributes
}

解决方案:

extension ConversationVC: UICollectionViewDelegateFlowLayout{

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

var height: CGFloat = 80

let message = messages[indexPath.item]

if let text = message.message {

height = estimateFrameForText(text).height + 20

} else if let imageWidth = message.imageWidth?.floatValue, let imageHeight = message.imageHeight?.floatValue{

height = CGFloat(imageHeight / imageWidth * 200)

}

let width = collectionView.frame.width - 40

return CGSize(width: width, height: height)
}

fileprivate func estimateFrameForText(_ text: String) -> CGRect {
let size = CGSize(width: 200, height: 1000)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
return NSString(string: text).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 16)], context: nil)

}

}//end extension

最佳答案

首先,让我们尝试找到出现此问题的确切位置。

尝试 1:

注释掉这一行

//self.chatPartnerProfileImg.sd_setImage(with: url, placeholderImage:  #imageLiteral(resourceName: "placeholder"), options: [.continueInBackground, .progressiveDownload], completed: nil)

然后运行您的应用以查看结果。

尝试 2:

将该行放在异步 block 中以查看结果。

DispatchQueue.main.async {
self.chatPartnerProfileImg.sd_setImage(with: url, placeholderImage: #imageLiteral(resourceName: "placeholder"), options: [.continueInBackground, .progressiveDownload], completed: nil)
}

尝试3:注释设置圆角半径的代码

/*self.layer.cornerRadius = 10.0
self.layer.shadowRadius = 5.0
self.layer.shadowOpacity = 0.3
self.layer.shadowOffset = CGSize(width: 5.0, height: 10.0)
self.clipsToBounds = false*/

分享您对尝试 1、2 和 3 的结果,然后我们可以更好地了解问题出在哪里。

希望通过这种方式我们可以找到闪烁背后的原因。

关于swift - 我的 UICollectionView 使用 Swift 滚动不流畅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51777827/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com