Unal Celik
Unal Celik

Reputation: 196

How to auto-resize UICollectionView when device rotates?

I'm trying to resize my collectionViewCells for every time i rotate device but i cant figure it out how. Here is my problem and my code. It's in Swift 3 and Xcode 8.

It's the first screen that we load 1

And when i rotate device cell's still has same width-height 2

On the other hand, if i load firstScreen(HomePage) when device is rotated (Landscape) and then i rotate device again to Portrait, the cells overflows so i cant see sides of them. Because width is still the same with Landscape width.

    // MARK: UICollectionViewDataSource

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

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

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

    // Configure the cell
    cell.imageView.image = allNews[indexPath.row].newsPic
    cell.textView.text = allNews[indexPath.row].newsTitle
    return cell
}

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


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}


// MARK: Orientation Changes ( reload the CollectionLayout )
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {

}

Last of all i didn't used Auto-Layout in Main.storyboard. Here is my setupViews() method in HomeCollectionViewCell class

    private func setupViews() {
    addSubview(imageView)
    addSubview(textView)
    addSubview(separatorView)
    addSubview(dateView)

    addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: imageView)
    addConstraintsWithFormat(format: "V:|-16-[v0]-8-[v1(40)]-2-[v2(20)]-8-|", views: imageView, textView, dateView)

    addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: textView)
    addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: dateView)

    addConstraintsWithFormat(format: "H:|[v0]|", views: separatorView)
    addConstraintsWithFormat(format: "V:[v0(1)]|", views: separatorView)
}

Regards.

SOLVED!: I used this method instead of override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    collectionView?.collectionViewLayout.invalidateLayout()
}

Upvotes: 3

Views: 5699

Answers (3)

Heo Đất Hades
Heo Đất Hades

Reputation: 1633

Because I have fixed number of row in collection view so I have to resize my cell size when device rotated. I hope this help:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    guard let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout else {
        return
    }

    if UIInterfaceOrientationIsLandscape(UIApplication.shared.statusBarOrientation) {
        //here you can do the logic for the cell size if phone is in landscape

    } else {
        //logic if not landscape
    }
    let cellSize =  CGSize(width: (size.width - CGFloat(row ))/CGFloat(row)  , height: 90)
    flowLayout.itemSize = cellSize
    flowLayout.invalidateLayout()
}

* row is my number of row, you can change it suitable for you.

Upvotes: 0

jhd
jhd

Reputation: 1253

See my solution.

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: 100, height: 100)
let controller = UICollectionViewController(collectionViewLayout: layout))

In iOS8+ the function is not override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {} anymore.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        if let layout =  self.collectionView?.collectionViewLayout as? UICollectionViewFlowLayout{
            layout.itemSize = CGSize(width: 200, height: 200)
        }
    }

This works for me. Try it.

Upvotes: 1

Chirag kukreja
Chirag kukreja

Reputation: 433

You should use self.view.bounds instead of self.view.frame because when device rotated frame remain same in both portrait and landscape only bound changes.

Upvotes: 1

Related Questions