elkefreed
elkefreed

Reputation: 964

Update UICollectionView Width on Device Rotate in Swift

I have custom keyboard with a UICollectionView. The cells do not have a defined size. When rotating the device from portrait to landscape the keyboard resizes appropriately but the UICollectionView stays at the original width.

What is the best way to tackle updating the width to expand to the full available with? How can I update the constraints to the available space?

The UICollectionView is created programmatically and I'm not using a storyboard to implement AutoLayout that way.

override func viewDidAppear(animated: Bool) {
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)

    collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)

    collectionView.dataSource = self
    collectionView.delegate = self

    collectionView.registerNib(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: kbReuseIdentifier)
    collectionView.backgroundColor = UIColor.whiteColor()
    self.collectionView.translatesAutoresizingMaskIntoConstraints = true

    self.view.addSubview(collectionView)

    let collectionViewBottomConstraint = NSLayoutConstraint(item: self.collectionView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: -40.0)
    let collectionViewTopConstraint = NSLayoutConstraint(item: self.collectionView, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1.0, constant: 10)
    let collectionViewLeftConstraint = NSLayoutConstraint(item: self.collectionView, attribute: .LeadingMargin, relatedBy: .Equal, toItem: self.view, attribute: .LeadingMargin, multiplier: 1.0, constant: 0)
    let collectionViewRightConstraint = NSLayoutConstraint(item: self.collectionView, attribute: .TrailingMargin, relatedBy: .Equal, toItem: self.view, attribute: .TrailingMargin, multiplier: 1.0, constant: 0)


    self.view.addConstraints([collectionViewBottomConstraint, collectionViewTopConstraint, collectionViewRightConstraint, collectionViewLeftConstraint])


}

Upvotes: 0

Views: 3085

Answers (2)

Thanos
Thanos

Reputation: 854

Try overriding updateViewConstraints, check what is the current orientation with UIInterfaceOrientationIsPortrait(UIApplication.sharedApplication().statusBarOrientation/UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation and update the constant of certain constraints in your NSAutoLayout logic.

Upvotes: 0

Eneko Alonso
Eneko Alonso

Reputation: 19682

You need to implement the UICollectionViewDelegateFlowLayout protocol on your view controller.

On viewDidLoad, register for orientation changed notifications:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationDidChange:", name: UIDeviceOrientationDidChangeNotification, object: nil)

Don't forget to remove the observer when the viewController is closed:

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

When the orientation changes, tell the collectionView to update the layout:

func orientationDidChange(notification: NSNotification) {
    collectionView!.collectionViewLayout.invalidateLayout()
}

Finally, implement the UICollectionViewDelegateFlowLayout protocol method. On this method you can calculate the size for your collection view cells as needed, by referencing the collectionView frame width or the device screen size:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    // Leave 10px margin on each side, plus 10px between columns
    let columns = 2
    let margings = 20 + 10 * (columns - 1)
    let width = (collectionView.frame.size.width - margings) / columns
    let height = width // square cells
    return CGSizeMake(width, height)
}

In my case, I want the cells to always be proportional to the portrait screen ratio. Also I have a variable number of columns, but that might not be your case.

Upvotes: 4

Related Questions