2016-09-20 2 views
0

У меня проблема, когда я использую представление коллекции с сегментомView.Вид коллекции с повторяющимися сегментами сегментов

У меня есть viewController, который имеет segmentView с 4-х элементов (0 => Все, 1 => Фото, 2 => Audios, 3 => видео) вот и пример:

enter image description here

И у меня есть один CollectionView для отображения данных зависит от категории щелкнул от segmentController

Он работает и отображение данных и вот мои CollectionView метод для отображения данных

// MARK: Datasource collection method 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     // All Items 

     if segmentStatues == 0 
     { 
      let cellForAll = collectionView.dequeueReusableCell(withReuseIdentifier: "AllItemsCell", for: indexPath) as! AllItemsCollectionViewCell 

      // reset elements before declare 

      cellForAll.cellImage.image = nil 
      cellForAll.playBtn.isHidden = true 

      cellForAll.layer.borderWidth = 1 
      cellForAll.layer.borderColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0).cgColor 
      // When type is an image 
      if sociaPosts[(indexPath as NSIndexPath).row].postType == "image" 
      { 

       cellForAll.cellImage.sd_setImage(with: URL(string: sociaPosts[(indexPath as NSIndexPath).row].postUrl)) 


      }else if sociaPosts[(indexPath as NSIndexPath).row].postType == "audio" 
      { 

       cellForAll.cellImage.image = UIImage(named: "recorde_icon") 


      }else if sociaPosts[(indexPath as NSIndexPath).row].postType == "video" 
      { 
       cellForAll.cellImage.sd_setImage(with: URL(string: sociaPosts[(indexPath as NSIndexPath).row].thumbURL)) 
       cellForAll.playBtn.isHidden = false 
      } 

      return cellForAll 

     }else{ 

      // Cell if Images or videos or audios 

      let newCell = collectionView.dequeueReusableCell(withReuseIdentifier: "beepbeep", for: indexPath) as! userProfileImageCollectionViewCell 

      // If the type is images 

      if segmentStatues == 1 
      { 
       // Set image URL 

       newCell.cellImage.sd_setImage(with: URL(string: imagesPosts[(indexPath as NSIndexPath).row].postUrl)) 

       // Get image likes and comments and shares 

       newCell.likeCount.text = String(imagesPosts[(indexPath as NSIndexPath).row].likes_count) 
       newCell.commentCount.text = String(imagesPosts[(indexPath as NSIndexPath).row].comments_count) 
       newCell.shareCount.text = String(imagesPosts[(indexPath as NSIndexPath).row].shares_count) 

      } else if segmentStatues == 3 
      { 
       // For Video player 

      var player = newCell.customVid 
      player = Bundle.main.loadNibNamed("VieoPlayer", owner: self, options: nil)?.last as? videoPlayer 

      player?.newIntitVideoPlayer(forViewController: self, videoURL: videosPosts[indexPath.row].postUrl , videoThumbnail: URL(string: videosPosts[indexPath.row].thumbURL), onReady: nil) 
       // Set video URL and Thumbnail 

       // Get video likes and comments and shares 
       newCell.likeCount.text = String(videosPosts[(indexPath as NSIndexPath).row].likes_count) 
       newCell.commentCount.text = String(videosPosts[(indexPath as NSIndexPath).row].comments_count) 
       newCell.shareCount.text = String(videosPosts[(indexPath as NSIndexPath).row].shares_count) 

      }else if segmentStatues == 2 
      { 
       // Audio player 
       let ad = Bundle.main.loadNibNamed("AudioPlayerView", owner: self, options: nil)?.last as! AudioPlayerView 
       ad.frame = CGRect(x: (newCell.contentView.frame.size.width - newCell.contentView.frame.size.height * 0.6)/2, y: 20 , width: newCell.contentView.frame.size.height * 0.6, height: newCell.contentView.frame.size.height * 0.6) 
       ad.playImageView.image = nil 

       ad.tag = 6666 

       newCell.contentView.addSubview(ad) 

       // Set audio URL 
       ad.audioPath = URL(string: audiosPosts[indexPath.row].postUrl) 
       ad.viewInitialization() 

       // Get Audio likes and comments and shares 
       newCell.likeCount.text = String(audiosPosts[(indexPath as NSIndexPath).row].likes_count) 
       newCell.commentCount.text = String(audiosPosts[(indexPath as NSIndexPath).row].comments_count) 
       newCell.shareCount.text = String(audiosPosts[(indexPath as NSIndexPath).row].shares_count) 

      } 
      return newCell 
     } 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

     if self.segmentStatues == 0 
     { 

      return sociaPosts.count 
     }else if self.segmentStatues == 1 
     { 
      return imagesPosts.count 
     }else if self.segmentStatues == 2 
     { 
      return audiosPosts.count 
     }else 
     { 
      return videosPosts.count 
     } 
    } 

у меня есть 2 пользовательских ячейки в моей точке зрения сбора один для всех элементов, а другие для (изображений - аудио - видео) вида

моя проблема заключается в данные отображения, но клетки дублируются, когда я изменяю между сегментом в userProfileImageCollectionViewCell

эти 2 фотографии показывают проблему

Отображение всех аудиозаписей ячейки, когда я нажимаю в аудио segmnet

enter image description here

Но после того, как я нажимаю на ячейки изображения или видео сегмента дублируется как это

enter image description here

это происходит в аудио - изображения - только видео ** (userProfileImageCollectionViewCell) **

и fin союзник вот мой userProfileImageCollectionViewCell код:

updateded:

import UIKit 
import SDWebImage 
class userProfileImageCollectionViewCell: UICollectionViewCell { 

    @IBOutlet weak var customVid: videoPlayer! 
    @IBOutlet weak var cellImage: UIImageView! 

    @IBOutlet weak var likeButton: UIButton! 

    @IBOutlet weak var likeCount: UILabel! 
    @IBOutlet weak var commentButton: UIButton! 

    @IBOutlet weak var commentCount: UILabel! 
    @IBOutlet weak var shareButton: UIButton! 
    @IBOutlet weak var shareCount: UILabel! 

    override func prepareForReuse() { 
     cellImage.sd_setImage(with: nil) 
     self.customVid.subviews.forEach({ $0.removeFromSuperview() }) 

    } 
} 
+0

В 'userProfileImageCollectionViewCell' в' prepareForReuse() 'сбросьте все значения (особенно те, которые могут присутствовать в одном случае и не присутствуют в другом). Иначе вы можете сделать это 'tableView: cellForRowAtIndexPath()', но поскольку у вас есть пользовательский файл для вашей ячейки, я бы рекомендовал сделать это в 'prepareForReuse()'. – Larme

+0

'collectionView.reloadData()' в вашем элементе segmentedController должно помочь вам. – Moriya

+0

Используйте только 'else' вместо' else if segmentStatues == 2' для последнего условия. –

ответ

1

Вопрос заключается в том, что UICollectionViewCell (а также UITableViewCell, кстати) повторно используются.

Проще говоря: Когда клетка исчезает с экрана при прокрутке, она может возвращаться вверху/внизу (в зависимости от направления прокрутки). Но это не новая «чистая» ячейка, это предыдущая. Это система повторного использования.

Итак, когда вы это сделали: newCell.contentView.addSubview(ad), вы каждый раз добавляли новое подзаголовок, не проверяя, был ли он уже установлен. Подглядывание, на котором сваливается juste. Это легко проверить с помощью 3D Hierarchy Debug of XCode.

Поскольку у вас есть файл userProfileImageCollectionViewCell, лучшим решением является использовать prepareForReuse(). Создайте IBOutlet (назовем его customVid), который добавит в качестве подзадачи объявление/плеер. prepareForReuse() удалить все подходы к customVid. В collectionView:cellForRowAtIndexPath:, сделать что-то вроде этого:

var player = Bundle.main.loadNibNamed("VieoPlayer", owner: self, options: nil)?.last as? videoPlayer 
player?.newIntitVideoPlayer(forViewController: self, videoURL: videosPosts 
newCell.customVid.addSubview(player) 

Репликация тот же самый механизм для ad (вы можете использовать один и тот же подвид, это до вас).

Теперь несколько предложений, не связанных с вашей проблемы:

Имя вашего класса, начиная с заглавной буквы: userProfileImageCollectionViewCell =>UserProfileImageCollectionViewCell

Я бы создать методы userProfileImageCollectionViewCell, чтобы сделать код более читаемым. Я не говорю Swift, поэтому мои следующие строки кода не может скомпилировать, но вы должны получить идею:

func fillWithVideo(videoParam video: CustomVideoClass) { 
    var player = newCell.customVid 
    player = Bundle.main.loadNibNamed("VieoPlayer", owner: self, options: nil)?.last as? videoPlayer 
    player?.newIntitVideoPlayer(forViewController: NOTself, videoURL: video.postUrl, videoThumbnail: URL(string: video.thumbURL), onReady: nil) 
    self.customVid.addSubview(player) 
    // Set video URL and Thumbnail 

    // Get video likes and comments and shares 
    self.likeCount.text = String(video.likes_count) 
    self.commentCount.text = String(video.comments_count) 
    self.shareCount.text = String(video.shares_count) 
} 

В collectionView:cellForRowAtIndexPath:

//If it's the correct section 
let video = videosPosts[(indexPath as NSIndexPath).row] as CustomVideoClass 
cell fillWithVideo(video) 

Обратите внимание, что, кажется, что вы используете UIViewController, поэтому вы можете добавить параметр UIViewController, чтобы получить метод newIntitVideoPlayer(), но я не хотел ставить его в предыдущем примере, чтобы сделать его более простым. Вы, возможно, потребуется заменить строки:

cell fillWithVideo(video andViewController:self) 

и

func fillWithVideo(videoParam video: CustomVideoClass andViewController viewController: UIViewController) 
player?.newIntitVideoPlayer(forViewController: viewController, videoURL: video.postUrl, videoThumbnail: URL(string: video.thumbURL), onReady: nil) 

Etc. для каждой части определенной части. Это упрощает чтение того, что вы делаете. Обрабатывайте только в collectionView:cellForRowAtIndexPath: логике (какая секция должна получить какой элемент и т. Д.), А остальная - в ячейку, которая может адаптироваться.

+0

Большое спасибо за ваш ответ и ваше объяснение :)) – Muhammed

Смежные вопросы