JSQMessagesViewController中JSQVideoMediaItem视频预览图显示异常
Hey there! Let's work through that frustrating black preview issue you're seeing with your video message bubbles. Since you confirmed your generateThumbnail() function is correctly fetching the right image from Firebase Storage, the problem almost certainly lies in how you're applying that image to the JSQVideoMediaItem or when you're updating the collection view. Here are the key fixes to try:
1. Always Update UI on the Main Thread
Firebase Storage calls run asynchronously on a background thread, and UI updates must happen on the main thread. If you're setting the thumbnail image without dispatching back to the main queue, the UI won't pick up the change at all.
2. Refresh the Collection View Cell After Setting the Thumbnail
When you get your preview image back, you need to tell the collection view to reload the specific cell so it can replace the default black placeholder with your fetched thumbnail.
Example Implementation
Here's how to adjust your code to address both points:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let message = messages[indexPath.row] guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: JSQMessagesCollectionViewCell.reuseIdentifier, for: indexPath) as? JSQMessagesCollectionViewCell else { return UICollectionViewCell() } if let videoMediaItem = message.media as? JSQVideoMediaItem { // Optional: Set a placeholder image first to avoid immediate blackness videoMediaItem.image = UIImage(named: "video-placeholder") // Set outgoing/incoming bubble mask correctly videoMediaItem.appliesMediaViewMaskAsOutgoing = message.isOutgoing // Fetch your thumbnail asynchronously generateThumbnail(from: message.videoStorageURL) { [weak self] previewImage in guard let self = self, let thumbnail = previewImage else { return } // Dispatch to main thread to safely update UI DispatchQueue.main.async { // Update the media item's thumbnail videoMediaItem.image = thumbnail // Reload the specific cell to render the new image self.collectionView.reloadItems(at: [indexPath]) } } cell.mediaView?.media = videoMediaItem } // Rest of your cell configuration (bubble color, avatar, etc.) return cell }
Additional Quick Checks
- Double-check that
appliesMediaViewMaskAsOutgoingmatches your message's direction (incoming/outgoing) — incorrect settings can sometimes break bubble rendering - Confirm your
previewImageisn't a zero-sized image (you mentioned print confirms it's valid, but this is a quick sanity check)
By making sure you update the image on the main thread and reload the cell after setting the thumbnail, your video previews should start showing up correctly instead of the black placeholder.
内容的提问来源于stack exchange,提问作者Ghiggz Pikkoro

