Ich implementiere einen einfachen Messenger für meine App, in dem die Benutzer untereinander chatten können. Der Messenger basiert auf UICollectionView (JSQMessagesViewController), wobei jede Nachricht durch eine UICollectionView-Zeile repräsentiert wird. Jede Nachricht hat auch eine obere Beschriftung, die verwendet wird, um anzuzeigen, wann die Nachricht gesendet wurde. Diese Beschriftung ist anfangs ausgeblendet (Höhe = 0) und wenn der Benutzer die bestimmte Nachricht (Zeile) antippt, wird die Beschriftung angezeigt, indem die Höhe entsprechend eingestellt wird. (height = 25)JSQMessagesView Probleme bei der Änderung der Zeilenhöhe
Das Problem, mit dem ich konfrontiert bin, ist die eigentliche Animation der Anzeige des Etiketts. (Höhenänderung). Ein Teil der Reihe überlagert die Reihe um einige Pixel, bevor sie an ihre Position gelangt. Wenn die Beschriftung zurückverdeckt wird, setzt die Animation zuerst die Höhe auf Null, und dann wird der Text ausgeblendet, der einen Teil der unteren Nachricht überlagert, was wirklich schlecht aussieht.
Also im Grunde, was ich versuche zu erreichen ist, diese beiden zuvor genannten Probleme loszuwerden.
Code:
override func collectionView(_ collectionView: JSQMessagesCollectionView!, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout!, heightForCellTopLabelAt indexPath: IndexPath!) -> CGFloat {
if indexPath == indexPathTapped {
return 25
}
let messageCurrent = messages[indexPath.item]
let messagePrev: JSQMessage? = indexPath.item - 1 >= 0 ? messages[indexPath.item - 1] : nil
if messageCurrent.senderId == messagePrev?.senderId || messagePrev == nil {
return 0
}
else{
return 25
}
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAt indexPath: IndexPath!) {
if let indexPathTapped = indexPathTapped, indexPathTapped == indexPath {
self.indexPathTapped = nil
}
else{
indexPathTapped = indexPath
}
collectionView.reloadItems(at: [indexPath])
// UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveLinear, animations: {
// collectionView.performBatchUpdates({
// collectionView.reloadItems(at: [indexPath])
// }, completion: nil)
// }, completion: nil)
}
Demo: (Sorry für die Qualität)
Ich würde wirklich schätzen, wenn jemand mir dabei helfen konnte, wie ich bereits ausgegeben haben mehrere Stunden versuchen, es herauszufinden, ohne irgendwo zu kommen.
Vielen Dank im Voraus!
EDIT:
ich die Lösung von @jamesk wie folgt vorgeschlagen versucht:
override func collectionView(_ collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAt indexPath: IndexPath!) {
if let indexPathTapped = indexPathTapped, indexPathTapped == indexPath {
self.indexPathTapped = nil
}
else{
indexPathTapped = indexPath
}
UIView.animate(withDuration: 0.25) {
collectionView.performBatchUpdates(nil)
}
}
Und überschreiben die apply
von JSQMessagesCollectionViewCell
:
extension JSQMessagesCollectionViewCell {
override open func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
layoutIfNeeded()
}
}
jedoch diese Änderungen in Folge:
Ich habe auch versucht die zweite Lösung mit dem Layout ungültig zu machen:
override func collectionView(_ collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAt indexPath: IndexPath!) {
if let indexPathTapped = indexPathTapped, indexPathTapped == indexPath {
self.indexPathTapped = nil
}
else{
indexPathTapped = indexPath
}
var paths = [IndexPath]()
let itemsCount = collectionView.numberOfItems(inSection: 0)
for i in indexPath.item...itemsCount - 1 {
paths.append(IndexPath(item: i, section: 0))
}
let context = JSQMessagesCollectionViewFlowLayoutInvalidationContext()
context.invalidateItems(at: paths)
UIView.animate(withDuration: 0.25) {
self.collectionView?.collectionViewLayout.invalidateLayout(with: context)
self.collectionView?.layoutIfNeeded()
}
}
die in der folgenden Folge:
Ich habe versucht, beide Lösungen, die Sie vorgeschlagen, aber keiner von ihnen funktioniert (siehe Frage EDIT). Hast du eine Ahnung, was schief gelaufen ist? – user3559787
Ich habe diese Dinge versucht, aber es funktioniert immer noch nicht. – user3559787
Ich denke, die einfachste wäre, wenn Sie nur einen Link zu Ihrem Beispiel (das Sie bereits haben). Ich werde sehen, was ich anders gemacht habe und es hier erneut hochladen. – user3559787