Why does UICollectionView log an error when the cells are fullscreen?
There is a property on UIViewController
–automaticallyAdjustsScrollViewInsets
–that defaults to YES
. This means that when a UIViewController
has a UIScrollView
in its view hierarchy–which is true of a UICollectionViewController
–the contentInset
property of that scroll view is adjusted automatically to account for screen areas consumed by the status bar, navigation bar, and toolbar or tab bar.
The documentation for that property states:
automaticallyAdjustsScrollViewInsets
Specifies whether or not the view controller should automatically adjust its scroll view insets.
@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
Discussion
Default value is YES, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set to NO if you want to manage scroll view inset adjustments yourself, such as
when there is more than one scroll view in the view hierarchy.
The solution is to set automaticallyAdjustsScrollViewInsets
to NO
somewhere in your UICollectionViewController
subclass, such as in viewDidLoad
:
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
}
I have put an example project on GitHub that illustrates this problem and solution. There are two branches: with_error
and fixed_error
. Here is a diff of the change on GitHub.
UICollectionViewCell not filling the entire screen in Swift 3
The correct Swift 3 implementation should be
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemWidth = collectionView.bounds.width
let itemHeight = collectionView.bounds.height
return CGSize(width: itemWidth, height: itemHeight)
}
This will make each collection view cell fill up the entire collection view. It should not be private. Now all you need to do is make sure your collection view stretches across the entire view.
Also make sure to extend your ViewController to include UICollectionViewDelegateFlowLayout for the above method to work and change all section insets to be 0 in Storyboard.
the behavior of the UICollectionViewFlowLayout is not defined, because the cell width is greater than collectionView width
This happens when your collection view resizes to something less wide (go from landscape to portrait mode, for example), and the cell becomes too large to fit.
Why is the cell becoming too large, as the collection view flow layout should be called and return a suitable size ?
collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath)
Update to include Swift 4
@objc override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{ ... }
This is because this function is not called, or at least not straight away.
What happens is that your collection view flow layout subclass does not override the shouldInvalidateLayoutForBoundsChange
function, which returns false
by default.
When this method returns false, the collection view first tries to go with the current cell size, detects a problem (which logs the warning) and then calls the flow layout to resize the cell.
This means 2 things :
1 - The warning in itself is not harmful
2 - You can get rid of it by simply overriding the shouldInvalidateLayoutForBoundsChange
function to return true.
In that case, the flow layout will always be called when the collection view bounds change.
UICollectionview cell/imageview not going full screen on tap
Your view cell is embedded in a view hierarchy, and most views clip their sub-views. To get a "full-screen" effect you're going to need to either (a) set parent views of your image view (the cell, the collectionView, anything that might be embedded in, etc) not not clip subviews (see: "clips to bounds") or (b) put your image in a view that is not embedded in those containers.
I don't recommend (a). Trying to set containers to allow child-views (your UIImageView) that are bigger than the container is kind of an anti-pattern that breaks the idea that containers manage and contain the display of their children.
For (b), what you would want to do is:
on Tap:
imageView = << create a new UIImageView >>
[self.view addSubview:imageView]
set imageView.image = collectionCell.imageView.image
set imageView.frame = << translated rect of the collectionCell.imageView.frame >>
... animate blowing your new imageView up to full-screen...
So you're basically treating the "tap on cell" action as a command to "create a new UIImageView to show the image, and animate that to full-screen."
Since the new image view is a direct child of the VC's root view, it can be sized full-screen without getting clipped by a parent view.
UICollectionView not fitting within view controller on certain Apple devices
You need to set the size of the UICollectionViewCell
dynamically, this is done in code and not on the storyboard.
override func viewDidLoad() {
let width = self.bounds.width // This is the width of the superview, in your case probably the `UIViewController`
let height = 70 // Your desired height, if you want it to full the superview, use self.bounds.height
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: width, height: self.bounds.height) // Sets the dimensions of your collection view cell.
}
How to expand collectionview cell to full screen
If you want to increase cell size to fit to your screen you can use this method.
Objective-C
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
}
Swift
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
//For entire screen size
let screenSize = UIScreen.main.bounds.size
return screenSize
//If you want to fit the size with the size of ViewController use bellow
let viewControllerSize = self.view.frame.size
return viewControllerSize
// Even you can set the cell to uicollectionview size
let cvRect = collectionView.frame
return CGSize(width: cvRect.width, height: cvRect.height)
}
Related Topics
Uipopovercontroller Dealloc Reached While Popover Is Still Visible
Show Search Bar in Navigation Bar Without Scrolling on iOS 11
How to Add Buttons to Navigation Controller Visible After Segueing
How to Use Avsamplebufferdisplaylayer in iOS 8 for Rtp H264 Streams with Gstreamer
Spacing Between Uitableviewcells
Rendering PDF in Uiwebview iOS 8, Causes a Black Border Around PDF
Adding Glow Effect to Uibutton - iOS
How to Tell If Your Code Is Running on an iPhone or an Iphone3G
Swift If Statement - Multiple Conditions Separated by Commas
Detect When a Webview Video Becomes Fullscreen on iOS8
How to Create a Release Build in Xcode
How to Get Selected Value from Uipickerview
Export Compliance in iOS App Submission
How to Compare Ssl Certificates Using Afnetworking
Swift - Instantiating a Navigation Controller Without Storyboards in App Delegate
Xcode Tabbed Application - Adding New Tab View