Home > database >  UICollectionView - sizeForItemAtIndexPath not calculated correctly
UICollectionView - sizeForItemAtIndexPath not calculated correctly

Time:10-04

I'm trying to achieve the following using UICollectionViewFlowLayout:enter image description here

Somehow the two small pics are not fitting, here's the code:

The code below is in C#, any correct answers in swift will be accepted :)

  nfloat cellSpacing = 4;

 [Export("collectionView:layout:sizeForItemAtIndexPath:")]
        public CGSize GetSizeForItem(UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
        {
            double width;

            if (_events[indexPath.Section].Moments.Count == 3)
            {
                CGSize size;
                width = _newsFeedController.View.Frame.Width/ 3;
                var height = width * 3;
                if (indexPath.Row == 0)
                {
                    size= new CGSize((width * 2)-(cellSpacing/2), height);
                    return size;
                }
                else
                {
                    size = new CGSize(width - (cellSpacing / 2), (height-cellSpacing)/2);
                    return size ;
                }
               
            }
           
        }

        [Export("collectionView:layout:minimumInteritemSpacingForSectionAtIndex:")]
        public nfloat GetMinimumInteritemSpacingForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section)
        {
            return 0;
        }
        [Export("collectionView:layout:insetForSectionAtIndex:")]
        public UIEdgeInsets GetInsetForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section)
        {
            return new UIEdgeInsets(0, 0, 0, 0);
        }
        [Export("collectionView:layout:minimumLineSpacingForSectionAtIndex:")]
        public nfloat GetMinimumLineSpacingForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section)
        {
            return cellSpacing;
        }


I also made manual calculations to make sure it fits with the padding, however that was the result no matter what I do:

enter image description here

BTW I have created similar combinations for 5 and 4 photos and it works well; not sure what I'm doing wrong here.

Appreciate the help. Thanks!

CodePudding user response:

There is no way to accomplish this with a flow layout.

UICollectionFlowLayout lays out items in rows, from left-to-right (or right-to-left) and then wraps onto a new row when there is no space available. After the first cell has been laid out, the second cell gets the height of the first cell (since that is the height of the row) and then centers its contents vertically. When the third cell is laid out, it notices that there is no space left on the first row and wraps onto a second row. In other words: the layout never reserves "left-over" space for the second cell and never goes back to fill it with the third cell.

Similar combinations can work if the layout is two smaller cells on top and then a larger one, full-width, below them. That is compatible with flow layout because it does not depend on going back. With a scrollDirection = .horizontal layout, what you are asking for is similarly possible, because then the layout would fill in columns one by one, from top to bottom, and the big cell would be fitted and then the two smaller ones. But - that means the entire collection view scrolls horizontally. There's no way to do that as part of a vertical layout.

What you are looking for is a grid/tiled or "masonry" layout, of which there are a few open source alternatives.

  • Related