Swift: How to refresh UICollectionView layout after rotation of the device
Add this function:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
myCollection.collectionViewLayout.invalidateLayout()
}
When you change the orientation, this function would be called.
How to auto-resize UICollectionView when device rotates?
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.
UICollectionView - resizing cells on device rotate - Swift
You might use viewWillLayoutSubviews
. This question should be helpful but this is bassically called whenever the view controller views is about to layout its subviews.
So your code will look like this:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else {
return
}
if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) {
//here you can do the logic for the cell size if phone is in landscape
} else {
//logic if not landscape
}
flowLayout.invalidateLayout()
}
Resizing UICollectionViewCells on rotation changes currently visible cells
You should handle content offset of your UICollectionView
, so in your view controller try to override viewWillTransitionToSize
function from UIContentContainer
protocol, like this:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
let offset = yourCollectionView?.contentOffset;
let width = yourCollectionView?.bounds.size.width;
let index = round(offset!.x / width!);
let newOffset = CGPointMake(index * size.width, offset!.y);
yourCollectionView?.setContentOffset(newOffset, animated: false)
coordinator.animateAlongsideTransition({ (context) in
yourCollectionView?.reloadData()
yourCollectionView?.setContentOffset(newOffset, animated: false)
}, completion: nil)
}
Calling invalidateLayout() or reloadData() to reload a UICollectionView created from storyboard after device rotation
Two problems were identified in the above situation.
Firstly, xcode was not creating an IBOutlet in my custom UITableViewCell by dragging a line between the storyboard and the .swift file (apparently a bug in some constellations). The solution was to type the code in manually, and ctrl-drag and drop this in reverse to the correct view in the storyboard.
@IBOutlet weak var myCollectionView: UICollectionView!
Secondly, because the collection view was instantiated in a custom UITableViewCell, it wasn't possible to use viewWillTransitionToSize:withTransitionCoordinator: or viewWillLayoutSubviews (table view methods). However, UITableViewCell does have the following, where .invalidateLayout() can be called:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
{
super.traitCollectionDidChange(previousTraitCollection)
guard previousTraitCollection != nil else
{ return }
myCollectionView.collectionViewLayout.invalidateLayout()
}
UICollectionView Rotation incorrect layout after rotation
Add this in your UIViewController
class
It will adjust your layout automatically while you change device orientation.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
guard let columnLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else {
return
}
columnLayout.invalidateLayout()
}
Update UICollectionView Width on Device Rotate in Swift
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.
Related Topics
How to Set Image in Tabbar Not Tint Color in iOS
How to Get Navigation Based Template Functionality in Swift Programming
Swift Uicolor Initializer - Compiler Error Only When Targeting Iphone5S
Catch an Exception for Invalid User Input in Swift
How to Cache or Preload Sklabelnode Font
Downloading Uiimage via Alamofireimage
Which Is the Best Way to Estimate Measure of Photographed Things
Uitableviewcells with Uibutton Overlaps While Scrolling
Getting Back a Date from a String
Xcode Process Launch Failed: Security
Updating to Latest Version of Cocoapods
Center Nstextattachment Image Next to Single Line Uilabel
Navigationbar Bar, Tint, and Title Text Color in iOS 8
Autolayout - Intrinsic Size of Uibutton Does Not Include Title Insets