Why Does Uicollectionview Log an Error When the Cells Are Fullscreen

Why does UICollectionView log an error when the cells are fullscreen?

There is a property on UIViewControllerautomaticallyAdjustsScrollViewInsets–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



Leave a reply



Submit