Я создаю функцию чата в этом приложении и испытываю что-то странное. Я не думаю, что UICollectionViewCells
используется повторно правильно. Когда вы отправляете новое сообщение или быстро прокручиваете, вы видите, что «пузырь» не отображается правильно, но если вы прокручиваете назад и вперед, они возвращаются к нормальному состоянию, вот 2 скриншота того, как это на самом деле выглядит :
class CurrentUserMessageLogCVCell: UICollectionViewCell {
let messageTextView: UITextView = {
let textView = UITextView()
textView.isSelectable = false
textView.isEditable = false
return textView
}()
let bubbleView: UIView = {
let view = UIView()
return view
}()
let bubbleImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(bubbleView)
addSubview(messageTextView)
bubbleView.addSubview(bubbleImageView)
bubbleImageView.topAnchor.constraint(equalTo: bubbleView.topAnchor).isActive = true
bubbleImageView.bottomAnchor.constraint(equalTo: bubbleView.bottomAnchor).isActive = true
bubbleImageView.leadingAnchor.constraint(equalTo: bubbleView.leadingAnchor, constant: 8).isActive = true
bubbleImageView.trailingAnchor.constraint(equalTo: bubbleView.trailingAnchor, constant: -8).isActive = true
}
override func prepareForReuse() {
super.prepareForReuse()
applyTheme()
updateView()
messageTextView.text = ""
bubbleImageView.image = UIImage(named: "")
}
var message: Message? {
didSet {
updateView()
}
}
func updateView() {
if let text = message?.text {
incomingOrOutgoingMessageWithCalculatedFrame(text: text)
messageTextView.text = text
}
}
func incomingOrOutgoingMessageWithCalculatedFrame(text: String) {
let size = CGSize(width: 0.66 * contentView.frame.width, height: .infinity)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
let estimatedFrame = NSString(string: text).boundingRect(with: size,
options: options,
attributes:[NSAttributedStringKey.font: UIFont(name: Fonts.OpenSans_Regular, size: 13)!],
context: nil)
if message?.fromId == Api.Users.CURRENT_USER?.uid {
// outgoing message
bubbleImageView.image = UIImage(named: "chat_bubble_outgoing")!.resizableImage(withCapInsets: UIEdgeInsets(top: 17, left: 21, bottom: 17, right: 21)).withRenderingMode(.alwaysTemplate)
bubbleImageView.tintColor = Theme.current.view_messageBubbleView_outgoing_backgroundColor
messageTextView.textColor = Theme.current.textView_messageBubble_incoming_textColor
bubbleView.frame = CGRect(x: contentView.frame.width - estimatedFrame.width - 50,
y: 0,
width: estimatedFrame.width + 50,
height: estimatedFrame.height + 20)
messageTextView.frame = CGRect(x: contentView.frame.width - estimatedFrame.width - 32,
y: 0,
width: estimatedFrame.width + 10,
height: estimatedFrame.height + 20)
}
else {
// incoming message
bubbleImageView.tintColor = Theme.current.view_messageBubbleView_incoming_backgroundColor
messageTextView.textColor = Theme.current.textView_messageBubble_outgoing_textColor
bubbleImageView.image = UIImage(named: "chat_bubble_incoming")!.resizableImage(withCapInsets: UIEdgeInsets(top: 17, left: 21, bottom: 17, right: 21)).withRenderingMode(.alwaysTemplate)
bubbleView.frame = CGRect(x: 0, y: 0, width: estimatedFrame.width + 50, height: estimatedFrame.height + 20)
messageTextView.frame = CGRect(x: 20, y: 0, width: estimatedFrame.width + 20, height: estimatedFrame.height + 20)
}
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return messages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: messageCellId, for: indexPath) as! CurrentUserMessageLogCVCell
let message = messages[indexPath.row]
cell.message = message
return cell
}
func registerCells() {
collectionView.register(CurrentUserMessageLogCVCell.self, forCellWithReuseIdentifier: messageCellId)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if let messageText = messages[indexPath.row].text {
let estimatedFrame = estimateFrameForText(text: messageText)
return CGSize(width: view.frame.width, height: estimatedFrame.height)
}
return CGSize(width: view.frame.width, height: 100)
}
private func estimateFrameForText(text: String) -> CGSize {
let size = CGSize(width: 0.66 * view.frame.width, height: .infinity)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
let estimatedFrame = NSString(string: text).boundingRect(with: size,
options: options,
attributes:[NSAttributedStringKey.font: UIFont(name: Fonts.OpenSans_Regular, size: 13)!],
context: nil)
return CGSize(width: view.frame.width, height: estimatedFrame.height + 20)
}
Есть идеи, что вызывает и как исправить это странное поведение?