2017-02-20 37 views
0

Я пытаюсь создать коллекциюView, которая может расширять несколько ячеек после того, как они были выбраны/задействованы или свернуты, когда они отменены, все отлично работает, когда ячейки остаются на экране, но как только расширенные ячейки покидают экран, я получаю неожиданное поведение.Как развернуть несколько UICollectionViewCells в ответном сообщении

Например, если я выбираю ячейку с IndexPath 0 и затем прокручиваю вниз, коснитесь ячейки с помощью IndexPath 8, прокрутите назад до ячейки с помощью IndexPath 0 (она уже свернута), я бы нажал на нее и прокрутил назад до ячейку с IndexPath 8 и коснитесь ее снова, она расширит + ячейку с IndexPath 10 тоже расширится.

CollectionView был реализован программно, а UICollectionViewCell был подклассифицирован.

ViewController, который держит UICollectionView:

import UIKit 

class CollectionViewController: UIViewController { 

    // MARK: - Properties 
    fileprivate var collectionView: UICollectionView! 

    var manipulateIndex: NSIndexPath? { 
     didSet { 
      collectionView.reloadItems(at: collectionView.indexPathsForSelectedItems!) 
     } 
    } 

    // MARK: - Lifecycle 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) 

     collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) 
     collectionView.dataSource = self 
     collectionView.delegate = self 
     collectionView.register(CustomCell.self, forCellWithReuseIdentifier: "Cell") 
     collectionView.backgroundColor = UIColor.white 
     self.view.addSubview(collectionView) 
    } 

} 

// MARK: - UICollectionViewDataSource 
extension CollectionViewController: UICollectionViewDataSource { 

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CustomCell 

     cell.textLabel.text = "\(indexPath.item)" 
     cell.backgroundColor = UIColor.orange 

     return cell 
    } 
} 

// MARK: - UICollectionViewDelegate 
extension CollectionViewController: UICollectionViewDelegate { 

    func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { 
     let cell = collectionView.cellForItem(at: indexPath) as! CustomCell 
     cell.expanded = !cell.expanded 

     manipulateIndex = indexPath as NSIndexPath 

     return false 
    } 
} 

// MARK: - UICollectionViewDelegateFlowLayout 
extension CollectionViewController: UICollectionViewDelegateFlowLayout { 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 

     if let cell = collectionView.cellForItem(at: indexPath) as? CustomCell { 
      if cell.expanded == true { 
       return CGSize(width: self.view.bounds.width - 20, height: 300) 
      } 

      if cell.expanded == false { 
       return CGSize(width: self.view.bounds.width - 20, height: 120.0) 
      } 
     } 

     return CGSize(width: self.view.bounds.width - 20, height: 120.0) 

    } 
} 

И подклассы обычай UICollectionViewCell:

import UIKit 

class CustomCell: UICollectionViewCell { 

    var expanded: Bool = false 
    var textLabel: UILabel! 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     textLabel = UILabel(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height/3)) 
     textLabel.font = UIFont.systemFont(ofSize: UIFont.smallSystemFontSize) 
     textLabel.textAlignment = .center 
     contentView.addSubview(textLabel) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

Пожалуйста, помогите и спасибо так много удивительного человека, который может помочь мне! :)

ответ

1

Попробуйте это:
Пример 1: Разверните только одну ячейку в то время
Примечание: Нет необходимости принимать расширенную переменную Ьоо в пользовательской ячейке

var section:Int? 
var preSection:Int? 
var expand:Bool = false 


extension ViewController: UICollectionViewDataSource { 

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CustomCell 

     cell.textLabel.text = "\(indexPath.item)" 
     cell.backgroundColor = UIColor.orange 

     return cell 
    } 
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 

     if (self.section != nil) { 
      self.preSection = self.section 
     } 

     self.section = indexPath.row 

     if self.preSection == self.section { 
      self.preSection = nil 
      self.section = nil 
     }else if (self.preSection != nil) { 
      self.expand = false 
     } 
     self.expand = !self.expand 
     self.collectionView.reloadItems(at: collectionView.indexPathsForSelectedItems!) 

    } 

} 


// MARK: - UICollectionViewDelegateFlowLayout 
extension ViewController: UICollectionViewDelegateFlowLayout { 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 

     if self.expand, let row = self.section, row == indexPath.row { 
      return CGSize(width: self.view.bounds.width - 20, height: 300) 
     }else{ 
      return CGSize(width: self.view.bounds.width - 20, height: 120.0) 
     } 

    } 
} 

Пример 2: Развернуть несколько соту

import UIKit 

class ViewController: UIViewController { 


    // MARK: - Properties 
    fileprivate var collectionView: UICollectionView! 
    var expandSection = [Bool]() 
    var items = [String]() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.items = ["A","B","C","D","E","F","G","H","J","K"] 
     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) 

     collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) 
     collectionView.dataSource = self 
     collectionView.delegate = self 
     collectionView.register(CustomCell.self, forCellWithReuseIdentifier: "Cell") 
     collectionView.backgroundColor = UIColor.white 
     self.expandSection = [Bool](repeating: false, count: self.items.count) 

     self.view.addSubview(collectionView) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 

extension ViewController: UICollectionViewDataSource { 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return self.items.count 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CustomCell 

     cell.textLabel.text = self.items[indexPath.row] 
     cell.backgroundColor = UIColor.orange 

     return cell 
    } 
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 

     self.expandSection[indexPath.row] = !self.expandSection[indexPath.row] 
     self.collectionView.reloadItems(at: collectionView.indexPathsForSelectedItems!) 
    } 

} 


// MARK: - UICollectionViewDelegateFlowLayout 
extension ViewController: UICollectionViewDelegateFlowLayout { 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 

     if self.expandSection[indexPath.row] { 
      return CGSize(width: self.view.bounds.width - 20, height: 300) 
     }else{ 
      return CGSize(width: self.view.bounds.width - 20, height: 120.0) 
     } 
    } 
} 
0

UICollectionView будет повторно использовать ваши ячейки для нескольких объектов в вашей модели данных. Вы не можете контролировать, какие ячейки повторно использовать, когда во время reloadItems Вы не должны предполагать, что состояние expanded в данной ячейке соответствует состоянию вашей модели данных. Вместо этого вы должны как-то держаться за состояние expanded в своей модели данных и переустанавливать это при каждом вызове cellForItemAt.

Другими словами, держите свое состояние в своей модели и задайте состояние ячейки в cellForItemAt, не держите его в самих ячейках.