     private func indexPathForTypingIndicatorView() -> IndexPath {
         let section = messagesCollectionView.numberOfSections - 2
         return IndexPath(item: 0, section: max(section, 0))
+    }
+
+    private func invalidateLayoutForTypingIndicatorChange() {
+        if !isTypingIndicatorViewHidden || !invalidateLayoutOnTypingIndicatorHidden {
+            let ctx = UICollectionViewFlowLayoutInvalidationContext()
+            ctx.invalidateSupplementaryElements(
+                ofKind: MessagesCollectionView.elementKindTypingIndicator,
+                at: [indexPathForTypingIndicatorView()]
+            )
+            invalidateLayout(with: ctx)
+        } else {
+            invalidateLayout()
+        }
     }
 
     // MARK: - Layout Invalidation

    }

    public func shouldDisplayTypingIndicatorView(at indexPath: IndexPath) -> Bool {
        guard !indexPath.isEmpty else { return false }
        let isLastIndexPath = indexPath.section == messagesCollectionView.numberOfSections - 1
        return isLastIndexPath && !isTypingIndicatorViewHidden
    }

        }
        isTypingIndicatorViewHidden = isHidden

        if animated {
            messagesCollectionView.performBatchUpdates({ [weak self] in
                self?.invalidateLayoutForTypingIndicatorChange()
                updates?()
            }, completion: completion)
        } else {
            invalidateLayoutForTypingIndicatorChange()
            updates?()
            completion?(true)
        }
    }

    // MARK: - Attributes
