Why CollectionView cell insider other collectionView has wrong size? - ios

I have a collectionView (nested) inside a collectionViewCell. When I open this VC, the cell inside nested collectionView have wrong size. After scroll down and up - everything is fine.
I think when I am scrolling method layoutSubviews are calling.
But when I added
cell.setNeedsLayout() cell.layoutIfNeeded()
inside func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) the result is not change.
Constraints:

i think problem is not with the size, it is from constraints.
Would you please share a snippet of your code

Related

UICollectionView cell creation bypassed `willDisplay cell:` call?

I have an UICollectionView with .layer.masksToBounds set to false.
I do this so that way I can achieve a fade-out effect of any cells that scroll out of the collection view's proper bounds.
In order to ensure that I don't display out of bounds cells (when the UICollectionView loads them in), I use the delegate callback:
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
// pseudo code
if !cell.frame.intersects(collectionView.frame) {
cell.alpha = 0
}
}
However, it appears this callback is not invoked when the CollectionView populates an out-of-bound cell?
While obviously I am always informed if a cell is constructed through the cell provider function (i.e. the function where I invoke the dequeueReusableCell call), I cannot determine whether the cell I construct is out of bounds.
Is there any way I can be informed of when the UICollectionView constructs an out-of-bounds cell?

Need to show all items, one item in a row

I have a collectionView that is populated from Firebase Realtime Database. It should work as whatsapp.
I have created a collectionView cell to show the messages in a label.
I have set the collectionView scroll direction to vertical.
I have set the cell height to 40, and here you have the method sizeForItemAt:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width:collectionView.frame.size.width, height:40)
}
The items are shown, but not at full width and not one item per row.
Here you have a screenshot:
What do I need to change to get each item in a row?
Seems the method is not getting called here. You need to set the delegate of collectionView to the class. Add this to viewDidLoad.
collectionView.delegate = self
Suggested Approach: My suggested approach for your requirement is to use UITableView. All the cells extend the entire width of the UITableView. You just need to provide the height of the cell by this method.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
40
}

UICollectionViewCell inside UICollectionView

I am trying to place UICollectionView inside UICollectionViewCell. I have prepared my cell in xib file using autolayout, same for cells inside collectionView.
But what about autolayout?
Some of my UICollectionViews inside my cell are different size that the others because of its content so I fail using sizeForItemAt indexPath: to calculate proper size.
Is there any fairly simple way to do this using autolayout, different from changing this main UICollectionView to UITableView with UITableViewAutomaticDimension as a heightForRowAt indexPath:?
EDIT:
To explain everything i've done so far to make this work i'll provide a cell layout:
and some algorithm to calculate cell's size:
First of all i declared an array of cells heights inside my UIViewController subclass like so:
fileprivate var cellsHeight: [CGFloat] = [].
After that inside UICollectionView delegate method collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell i am populating this array with height of each individual collectionView content size like so:
let cell = collectionView.dequeueReusableCell...
if cell.collectionView != nil {
cellsHeight.append(cell.collectionView.collectionViewLayout.collectionViewContentSize.height)
}
And then in inside collectionView(_ collectionView: UICollectionView, sizeForItemAt indexPath: IndexPath) -> CGSize i am calculating each label size using boundingRect method, adding up some padding and previously fetched collectionView height.
But i think this is a pretty overkill.

How to force layout of collection view without compromising on the performance?

Here's my problem. I have a UICollectionViewCell having an image View. The image is downloaded from a link. The images are of different sizes and I want the collectionView cell size to change with the image size. I am currently accomplishing this by forcing the layout inside
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath)
by placing this line of code in it
collectionViewTrending.reloadItemsAtIndexPaths([indexPath])
The below UICollectionViewDelegate function
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath)
is handling the resizing of the cell.
Though this is working but it definitely is NOT efficient. It is inefficient because scrolling on the collectionView is taking longer and it is not smooth. Is there any way in which I can resize the cell without degrading the performance?
Remove that line--collectionViewTrending.reloadItemsAtIndexPaths([indexPath]) first..
Then set sizeForItem method of collectionView properly..It will work fine..

Which method to setup UIview?

The cells in my collectionView contains a UIView that should have a shadow. The problem is that if I set the shadow in the cell's AwakeFromNib method the shadow will be applied to the UIView before it has the correct size (which means the shadow will have a different size than the UIView). Which method is called when the cell and all its subviews have been correctly loaded and setup?
you can do any UI related work for collection view in this delegate method
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath)
It will always work

Resources