I\'m trying to program an expandable UICollectionViewCell. If the user presses the topbutton, the cell should expand to a different height and reveal the underlying content.
If you have more than cell that needs to be expanded to different height when a button is touched inside the collection view cell, then, here is the code.
I have used the delegate pattern to let the controller know, button of which cell was touched using the indexPath. You need to pass the indexpath of the cell to the cell when creating the cell.
when the button is touched the cell calls the delegate(ViewController), which updates the isExpandedArray accordingly and reloads the particular cell.
CollectionViewCell
protocol ExpandedCellDelegate:NSObjectProtocol{
func topButtonTouched(indexPath:IndexPath)
}
class ExpandableCell: UICollectionViewCell {
@IBOutlet weak var topButton: UIButton!
weak var delegate:ExpandedCellDelegate?
public var indexPath:IndexPath!
@IBAction func topButtonTouched(_ sender: UIButton) {
if let delegate = self.delegate{
delegate.topButtonTouched(indexPath: indexPath)
}
}
}
View Controller Class
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var expandedCellIdentifier = "ExpandableCell"
var cellWidth:CGFloat{
return collectionView.frame.size.width
}
var expandedHeight : CGFloat = 200
var notExpandedHeight : CGFloat = 50
var dataSource = ["data0","data1","data2","data3","data4"]
var isExpanded = [Bool]()
override func viewDidLoad() {
super.viewDidLoad()
isExpanded = Array(repeating: false, count: dataSource.count)
}
}
extension ViewController:UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: expandedCellIdentifier, for: indexPath) as! ExpandableCell
cell.indexPath = indexPath
cell.delegate = self
//configure Cell
return cell
}
}
extension ViewController:UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if isExpanded[indexPath.row] == true{
return CGSize(width: cellWidth, height: expandedHeight)
}else{
return CGSize(width: cellWidth, height: notExpandedHeight)
}
}
}
extension ViewController:ExpandedCellDelegate{
func topButtonTouched(indexPath: IndexPath) {
isExpanded[indexPath.row] = !isExpanded[indexPath.row]
UIView.animate(withDuration: 0.8, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.9, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.collectionView.reloadItems(at: [indexPath])
}, completion: { success in
print("success")
})
}
}