Daniel Dramond
Daniel Dramond

Reputation: 1598

Tap button to change UICollectionView Cell size?

I have a collection view on my HomeController (UICollectionView) Class and my PostCell (UICollectionViewCell) class. HomeController has just 4 different cells. I also have a button inside my PostCell that when touched, handles a handleChangeSize function. When I touch that button, I want that specific cells size to change. Preferably change in height, similar to Instagrams "show more" feature on their cells. Any help will be highly, highly appreciated. Thank you... Here's my code:

class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

        let cellId = "cellId"

        override func viewDidLoad() {
            super.viewDidLoad()
            collectionView?.backgroundColor = UIColor(white: 0.90, alpha: 1.0)

            collectionView?.register(PostCell.self, forCellWithReuseIdentifier: cellId)
            collectionView?.showsVerticalScrollIndicator = false
            collectionView?.alwaysBounceVertical = true
        }

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

        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! PostCell
            return cell
        }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            let height = (view.frame.width) * 9 / 16
            return CGSize(width: view.frame.width, height: height + 50 + 50)
    }
}

class PostCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    lazy var myButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Change Size", for: .normal)

        button.addTarget(self, action: #selector(handleChangeSize), for: .touchUpInside)

        return button
    }()

    func handleChangeSize() {

    }



    func setupViews() {
        addSubview(myButton)

        myButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        myButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    }

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

Upvotes: 3

Views: 3270

Answers (2)

Ganesh Kumar
Ganesh Kumar

Reputation: 1651

I have done this in tableView. follow the same for collectionView.

var expandedCells = [Int]()

here is the cellForRowAtIndexPath method

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "RequestTableViewCell") as! RequestTableViewCell
    cell.selectionStyle = .none
    cell.optionButton.tag = indexPath.row
    cell.optionButton?.addTarget(self, action: #selector(RequestsViewController.deleteAction), for: UIControlEvents.touchUpInside)
    return cell
  }

and the action for option button in tableViewCell is

func deleteAction(_ sender: UIButton){
    if let button = sender as? UIButton {
      // If the array contains the button that was pressed, then remove that button from the array
      if expandedCells.contains(sender.tag) {
        expandedCells = expandedCells.filter { $0 != sender.tag }
      }
        // Otherwise, add the button to the array
      else {
        expandedCells.removeAll()
        expandedCells.append(sender.tag)
      }
      // Reload the tableView data anytime a button is pressed
      self.requestTableView.beginUpdates()
      self.requestTableView.endUpdates()

    }
  }

and the heightForRowAtIndexPath method is

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Set the row height based on whether or not the Int associated with that row is contained in the expandedCells array
    if expandedCells.contains(indexPath.row) {
      return 112
    } else {
      return 67
    }
  }

Upvotes: 2

ossmalpha
ossmalpha

Reputation: 881

The solution to this problem is quite easy. First, you need to specify what height you want to set for the particular cell and perform that change in handleChangeSize() method (this could be done by simple frame.size.height = ...).

After that, you probably need to resize the whole collection view, otherwise, there are going to be some nasty surprises for you. Perform the calculation (to get the new height) after you have resized the cell (you might call a notification or something that triggers whenever a to resize is necessary).

Upvotes: -1

Related Questions