1

Target: I have a UICollectionView with default 7 columns and 6 rows of cells. Now the user shall be able to change the amount of columns and rows via a UIStepper. Like so:

var numberOfColumns: Int = 7

@IBAction func changeNumberOfColumns(_ sender: UIStepper) {
    numberOfColumns = Int(sender.value)
    boardSizingCollectionView.reloadData()
}

extension BoardSizingViewController: UICollectionViewDataSource {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return numberOfRows
    }

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

    func collectionView(_ collectionsiView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Field", for: indexPath) as! FieldCollectionViewCell
        cell.tokenView.backgroundColor = .white
        cell.tokenView.layer.cornerRadius = (cell.frame.width - 8 * 2) / 2
        return cell
    }
}

The cells shall keep their size, instead the UICollectionView shall be resized.

Problem: I can't directly set the width and height of a UICollectionView in code, because these are get-only properties. Also if I use

boardSizingCollectionView.frame.size = CGSize(width: FieldCollectionViewCell.frame.width * numberOfColumns, height: FieldCollectionViewCell.frame.height * numberOfRows)

I get an error, because my FieldCollectionViewCell is a CGRect and i don't know how to exactly access the size of a CGRect.

Another hook in the flesh is, that myCollectionView has constraints for it's x and y position, to be auto-positioned on different devices so myCollectionView has to get a width and a height at least in viewDidLoad().

Any hints for me? Thank you very much in forward!

procra
  • 535
  • 4
  • 29

2 Answers2

0

You can not modify the frame directly. But, You can assign a new frame for the question.

I can't directly set the width and height of a UICollectionView in code, because these are get-only properties. Also if I use

    //get the current frame
    var collectionViewFrame = self.collectionView.frame 
    //set the size
    collectionViewFrame.size = CGSize(width: FieldCollectionViewCell.frame.width * numberOfColumns, height: FieldCollectionViewCell.frame.height * numberOfRows) 
    //again set the frame
    self.collectionView.frame = collectionViewFrame
Joe
  • 8,868
  • 8
  • 37
  • 59
Shankar BS
  • 8,394
  • 6
  • 41
  • 53
  • That's what i planned to do that every time UIStepper.value is changed i reassign a new frame and hit collectionView.reloadData(). Unfortunately FieldCollectionViewCell is a CGRect, so i can't use FieldCollectionView.frame.something. It would be very helpful if there's a way to access the CGSize of FieldCollectionViewCell. – procra Apr 25 '17 at 10:42
0

Maybe try a different approach in constraining your collection view in storyboard, such that you are able to change the height through constraints. One way would be to give it a height constraint, and connect an outlet to your view controller. This way you can do

collectionViewHeightConstraint.constant = 
  FieldCollectionViewCell.frame.height * numberOfRows

collectionView.layoutIfNeeded()
collectionView.reloadData()

Similarly, giving the collection view a top and bottom constraint, then changing the bottom constraint also works, if you can’t give it a height constraint.

I haven't try the code yet let me know if it works :)

Chan Jing Hong
  • 2,251
  • 4
  • 22
  • 41
  • well the expression `FieldCollectionViewCell.frame.height` doesn't work so far cause it's a CGRect. I'm now trying to add a constraint for the CollectionView so it has a proportional height to the total view. By updating the number of rows or columns i will change the aspect ratio, so the width will be auto-adjusted – procra Apr 25 '17 at 13:13