Intro
Каждый раз, когда пользователь отправляет комментарий, он загружается в базу данных. После того, как это произошло, collectionView перезагружается. Однако перезагрузка не имеет ожидаемого поведения . Вместо добавления одного комментария в конец collectionView кажется, что он случайным образом складывает некоторые другие ячейки комментариев и отображает только две ячейки комментариев, независимо от того, сколько комментариев есть.
Это На выходе отладчика View вы можете четко видеть, что ячейки collectionView сложены:
На этом этапе я хотел бы уточнить, что это не ошибка размеров ячеек. Всем им назначен правильный размер, и , если я вызову reloadData в collectionView, в , более поздний момент времени , все ячейки отображаются правильно .
Я думаю, что все станет более ясным, если вы посмотрите на GIF:
Я действительно понятия не имею, откуда возникла эта ошибка или как ее исправить.
Код
Инициализация collectionView
private lazy var timelineCollectionView: UICollectionView = {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .vertical
flowLayout.estimatedItemSize = CGSize(width: self.view.frame.width, height: 10)
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
let cv = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
cv.contentInsetAdjustmentBehavior = .never
cv.backgroundColor = .clear
cv.scrollIndicatorInsets = UIEdgeInsets(top: self.coloredTitleBarHeight - self.getStatusBarHeight(), left: 0, bottom: 0, right: 0)
cv.delegate = self
cv.dataSource = self
cv.register(TLContentCell.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "content-header-cell")
cv.register(TLContentCell.self, forCellWithReuseIdentifier: "comment-cell")
return cv
}()
Код методов UICollectionViewDelegate:
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let cell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "content-header-cell", for: indexPath) as! TLContentCell
cell.isHeaderCell = true
cell.timelineContent = tlContentItem
cell.delegate = self
cell.isUserInteractionEnabled = true
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return commentItems.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "comment-cell", for: indexPath) as! TLContentCell
cell.delegate = self
cell.timelineContent = TLContent(nativeContentItem: commentItems[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
let indexPath = IndexPath(row: 0, section: section)
let headerView = self.collectionView(collectionView, viewForSupplementaryElementOfKind: UICollectionView.elementKindSectionHeader, at: indexPath) as! TLContentCell
return headerView.contentView.systemLayoutSizeFitting(CGSize(width: collectionView.frame.width, height: UIView.layoutFittingExpandedSize.height),
withHorizontalFittingPriority: .required, // Width is fixed
verticalFittingPriority: .fittingSizeLevel) // Height can be as large as needed
}
Код функции обработчика загрузки комментариев:
@objc func submitComment() {
submitCommentButton.isEnabled = false
submitCommentButton.backgroundColor = ColorCodes.lightGray
guard let user = Auth.auth().currentUser else {
print("No user detected. Redirecting to the login screen!")
self.displayWelcomeScreen()
return
}
guard commentTextView.text.count > 0, let commentContent = commentTextView.text else { print("Submission of comment aborted due to empty content."); return }
commentTextView.resignFirstResponder()
commentTextView.text = ""
calculateTextViewSize()
ContentUploader.uploadComment(uid: user.uid, content: NativeContentBase(msg: commentContent, usersTagged: [], topicsTagged: [], mediaAssigned: []), referencedContent: tlContentItem.nativeContent.contentId) { (error, comment) in
if let err = error {
print("An error occured during the comment upload: ", err)
return
}
print("Successfully uploaded comment!")
self.commentItems.append(comment)
DispatchQueue.main.async {
print(self.commentItems.count)
self.timelineCollectionView.reloadData()
}
}
print("Comment scheduled for submission!")
}
Я также убедился, что я Я нахожусь в основном потоке при вызове функции reloadData (). Однако странное поведение сохраняется.
Чтобы настроить contentInset
и scrollIndicatorInsets
collectionView на отображение клавиатуры, Я использую эти две функции :
private func adjustScrollBehavior() {
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
let bottomSafeAreaHeight = window?.safeAreaInsets.bottom ?? 0
// adjust the content Inset of the timelineCollectionView
let heightOfCommentSection: CGFloat = commentTextViewHeightAnchor.constant + abs(commentTextViewBottomAnchor.constant) + 8 // get the absolute value of the bottomAnchor's constant as it would be negative
timelineCollectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: heightOfCommentSection + bottomSafeAreaHeight, right: 0) // does not automatically take care of safe area insets
timelineCollectionView.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: heightOfCommentSection, right: 0) // automatically takes care of safe area insets
}
func calculateTextViewSize() {
let minimumSize = commentTextView.layoutMargins.top + commentTextView.layoutMargins.bottom + commentTextView.font!.lineHeight
let fixedWidth = self.view.frame.width - 32
let maximumSize: CGFloat = 155
let newSize = commentTextView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
print(newSize)
if newSize.height > minimumSize && newSize.height <= maximumSize {
commentTextViewHeightAnchor.constant = newSize.height
} else {
commentTextViewHeightAnchor.constant = newSize.height > minimumSize ? maximumSize : minimumSize
}
adjustScrollBehavior()
}
Закрытие
Я знаю, что это много кода, но в основном это все, что я использую. Я понятия не имею, почему это происходит, и я был бы невероятно благодарен за любую помощь, которую я мог получить.
Большое спасибо за вашу помощь:)