public override void PrepareLayout()
        {
            isPreparing = true;
            layoutCache = new List <UICollectionViewLayoutAttributes>();
            var numberOfItems = CollectionView.NumberOfItemsInSection(0);

            nfloat currentY = 0;

            for (var i = 0; i < numberOfItems; i++)
            {
                var viewSource = CollectionView.Source as ChatCollectionViewSource;
                var indexPath  = NSIndexPath.FromItemSection(i, 0);
                var cell       = viewSource.GetCell(CollectionView, indexPath) as ChatMessageCollectionViewCell;
                var size       = cell.ContentView.SystemLayoutSizeFittingSize(UIScreen.MainScreen.Bounds.Size);

                CGRect frame = new CGRect
                {
                    X      = 0,
                    Y      = currentY,
                    Width  = size.Width,
                    Height = size.Height,
                };

                var attributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
                attributes.Frame = frame;

                layoutCache.Add(attributes);

                currentY += frame.Height;
            }

            contentHeight = currentY;

            isPreparing = false;
        }
 public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath path)
 {
     UICollectionViewLayoutAttributes attributes = UICollectionViewLayoutAttributes.CreateForCell(path);
     attributes.Size = new CGSize(ItemSize, ItemSize);
     attributes.Center = new CGPoint(
         _center.X + _radius * (float)Math.Cos(2 * path.Row * Math.PI / _cellCount),
         _center.Y + _radius * (float)Math.Sin(2 * path.Row * Math.PI / _cellCount));
     return attributes;
 }
Exemplo n.º 3
0
        public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath path)
        {
            UICollectionViewLayoutAttributes attributes = UICollectionViewLayoutAttributes.CreateForCell(path);

            attributes.Size   = new SizeF(ItemSize, ItemSize);
            attributes.Center = new PointF(center.X + radius * (float)Math.Cos(2 * path.Row * Math.PI / cellCount),
                                           center.Y + radius * (float)Math.Sin(2 * path.Row * Math.PI / cellCount));
            return(attributes);
        }
Exemplo n.º 4
0
        // return layout attributes for a a specific item
        public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath path)
        {
            UICollectionViewLayoutAttributes attributes = UICollectionViewLayoutAttributes.CreateForCell(path);

            attributes.Size   = ItemSize;
            attributes.Center = new PointF(center.X + radius * (float)Math.Cos(2 * path.Row * Math.PI / count),
                                           center.Y + radius * (float)Math.Sin(2 * path.Row * Math.PI / count));
            attributes.Transform3D = CATransform3D.MakeScale(0.5f, 0.5f, 1.0f);
            return(attributes);
        }
        public override UICollectionViewLayoutAttributes LayoutAttributesForSupplementaryView(NSString kind, NSIndexPath indexPath)
        {
            var layoutAttributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);

            var cachedAttrs = _cache.FirstOrDefault(x => x.IndexPath == indexPath && x.RepresentedElementCategory == UICollectionElementCategory.SupplementaryView);

            if (cachedAttrs != null)
            {
                layoutAttributes = cachedAttrs;
            }

            return(layoutAttributes);
        }
        /// <summary>
        /// Provides a UICollectionViewLayoutAttributes for the current ListViewSource.
        /// </summary>
        /// <remarks>
        /// Use this method instead of UICollectionViewLayoutAttributes.CreateForCell, as the interop call
        /// is quite costly.
        /// </remarks>
        protected UICollectionViewLayoutAttributes GetLayoutAttributesForIndexPath(int row, int section)
        {
            var key = CachedTuple.Create(row, section);
            UICollectionViewLayoutAttributes attributes;

            if (!_layoutAttributesForIndexPaths.TryGetValue(key, out attributes))
            {
                var indexPath = GetNSIndexPathFromRowSection(row, section);
                _layoutAttributesForIndexPaths.Add(key, attributes = UICollectionViewLayoutAttributes.CreateForCell <UICollectionViewLayoutAttributes>(indexPath));
            }

            return(attributes);
        }
        /// <summary>
        /// Layouts the attributes for item.
        /// </summary>
        /// <returns>The attributes for item.</returns>
        /// <param name="path">Path.</param>
        public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath path)
        {
            var attributes = UICollectionViewLayoutAttributes.CreateForCell(path);

            var item  = _items[path.Row];
            var scale = widthScales[item.Layout];
            var width = CollectionViewContentSize.Width * scale;

            // make sure top and left elements aren't spaced from borders
            // if cell wants spacing disabled, we set spacing to 0
            var xSpacing = item.UseXSpacing ? _currentX > 0 ? _itemXSpacing : 0 : 0;
            var ySpacing = item.UseYSpacing ? _currentY > 0 ? _itemYSpacing : 0 : 0;

            // check first if we have started a new, we want to record the total height from everyline to resize the content size
            if (_currentLine < 0.01)
            {
                _currentHeight += item.Height + ySpacing;
            }

            _currentLine += scale + item.XSpacingScale;

            // avoids tiny gaps when not using x spacing
            var minorAdj = item.UseXSpacing ? 0 : 0.1;

            // HeightCalculated determines whether we want the layout to calculate the height, this is used when we dont want the collection view scrollable,
            // so the layout will calculate space available and divide between all other items with HeightCalculated set to true
            attributes.Frame = new CGRect(_currentX + xSpacing - minorAdj, _currentY + ySpacing, width - xSpacing + minorAdj, item.Height);

            // we only jump to a new line when we are on a cell with right or fill layout
            if (_currentLine < 0.99)
            {
                _currentX += width + (CollectionViewContentSize.Width * item.XSpacingScale);
            }
            else
            {
                _currentX    = 0;
                _currentLine = 0;
            }

            // check again for a new line to increase the currentY for the starting element on a new line
            if (_currentLine < 0.01)
            {
                _currentY += item.Height + ySpacing;
                _numberOfLines++;
            }

            return(attributes);
        }
        private void PlaceItem()
        {
            for (int i = 0; i < itemCount; i++)
            {
                var indexPath   = NSIndexPath.FromItemSection(i, 0);
                var itemHeight  = Delegate.HeightForItem(CollectionView, this, indexPath);
                var columnIndex = ShortestColumnIndex();

                var xOffset = sectionInset.Left + (itemWidth + interItemSpacing) * columnIndex;
                var yOffset = columnHeights[columnIndex];

                var attributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
                attributes.Frame = new RectangleF(xOffset, yOffset, itemWidth, itemHeight);
                itemAttributes.Add(attributes);
                columnHeights[columnIndex] = yOffset + itemHeight + interItemSpacing;
            }
        }
Exemplo n.º 9
0
        public override void PrepareLayout()
        {
            base.PrepareLayout();
            calculatedAttributes.Clear();

            contentWidth = CollectionView.Frame.Width;
            nfloat columnWidth = contentWidth / NumberOfColumns;
            nfloat height      = columnWidth * 1.25f; // Our cells height is a 25% greater than their width

            for (int i = 0; i < columnsXOffset.Length; i++)
            {
                columnsXOffset[i] = i * columnWidth;
            }

            for (int i = 0; i < columnsYOffset.Length; i++)
            {
                columnsYOffset[i] = 0;
            }

            UICollectionViewLayoutAttributes attribute1 = UICollectionViewLayoutAttributes.CreateForCell(NSIndexPath.FromItemSection(0, 0));

            attribute1.Frame = new CGRect(columnsXOffset[1], 0, columnWidth, buttonHeight);
            calculatedAttributes.Add(attribute1);

            columnsYOffset[1] = buttonHeight; // Second column has a vertical offset (due to sell button height)

            int column = 0;

            for (int i = 0; i < CollectionView.NumberOfItemsInSection(1); i++)
            {
                var indexPath  = NSIndexPath.FromItemSection(i, 1);
                var frame      = new CGRect(columnsXOffset[column], columnsYOffset[column], columnWidth, height);
                var insetFrame = RectangleFExtensions.Inset(frame, 0f, 0f);

                UICollectionViewLayoutAttributes attribute = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
                attribute.Frame = insetFrame;

                calculatedAttributes.Add(attribute);

                contentHeight          = System.NMath.Max(contentHeight, RectangleFExtensions.GetMaxY(frame));
                columnsYOffset[column] = columnsYOffset[column] + height;

                column = column >= (NumberOfColumns - 1) ? 0 : ++column;
            }
        }
Exemplo n.º 10
0
        public override void PrepareLayout()
        {
            Cache.Clear();

            var    standardHeight = CustomFlowLayoutConstants.Cell.standardHeight;
            var    featuredHeight = CustomFlowLayoutConstants.Cell.featuredHeight;
            var    frame          = CGRect.Empty;
            nfloat y = 0;

            for (int item = 0; item < NumberOfItems; item++)
            {
                var indexPath  = NSIndexPath.FromItemSection(item, 0);
                var attributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);

                attributes.ZIndex = item;
                var height = standardHeight;
                if ((indexPath.Item == FeaturedItemIndex))
                {
                    var yOffset = standardHeight * NextItemPercentageOffset;
                    y      = CollectionView.ContentOffset.Y - yOffset;
                    height = featuredHeight;
                }
                else if ((indexPath.Item == (FeaturedItemIndex + 1)) && (indexPath.Item != NumberOfItems))
                {
                    var y0   = y;
                    var maxY = y + standardHeight;
                    height = standardHeight + (nfloat)Math.Max((featuredHeight - standardHeight) * NextItemPercentageOffset, 0);
                    y      = maxY - height;
                    var fr = Cache[FeaturedItemIndex].Frame;
                    fr.Height -= y0 - y;
                    Cache[FeaturedItemIndex].Frame = fr;
                }
                else
                {
                    height = standardHeight;
                }

                frame            = new CGRect(0, y, Width, height);
                attributes.Frame = frame;

                Cache.Add(attributes);

                y = frame.GetMaxY();
            }
        }
Exemplo n.º 11
0
        public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath indexPath)
        {
            var cellAttributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);

            var column = indexPath.Item % columnCount;
            var row    = (int)indexPath.Item / columnCount;

            var frame = new CGRect
            {
                X      = cellWidth * column + CollectionView.Frame.Width * indexPath.Section,
                Y      = CellHeight * row,
                Width  = cellWidth,
                Height = CellHeight
            };

            cellAttributes.Frame = frame;

            return(cellAttributes);
        }
Exemplo n.º 12
0
        public override void PrepareLayout()
        {
            CGSize  size   = CollectionView.Bounds.Size;
            CGPoint center = new CGPoint(size.Width / 2.0f, size.Height / 2.0f);

            int itemCount = (int)CollectionView.NumberOfItemsInSection(0);

            if (attributesArray == null)
            {
                attributesArray = new List <UICollectionViewLayoutAttributes> (itemCount);
            }

            angles.Clear();

            float maxAngle = (float)(1 / Math.PI / 3.0f);
            float minAngle = -maxAngle;
            float diff     = maxAngle - minAngle;

            angles.Add(0);
            for (int i = 1; i < stackCount * 10; i++)
            {
                int hash = (int)(i * 2654435761 % 2 ^ 32);
                hash = (int)(hash * 2654435761 % 2 ^ 32);

                float currentAngle = (float)((hash % 1000) / 1000.0 * diff) + minAngle;
                angles.Add(currentAngle);
            }

            for (int i = 0; i < itemCount; i++)
            {
                int   angleIndex = i % (stackCount * 10);
                float angle      = angles [angleIndex];
                var   path       = NSIndexPath.FromItemSection(i, 0);
                UICollectionViewLayoutAttributes attributes = UICollectionViewLayoutAttributes.CreateForCell(path);
                attributes.Size      = new CGSize(150, 200);
                attributes.Center    = center;
                attributes.Transform = CGAffineTransform.MakeRotation(angle);
                attributes.Alpha     = (i > stackCount) ? 0.0f : 1.0f;
                attributes.ZIndex    = (itemCount - i);
                attributesArray.Add(attributes);
            }
        }
Exemplo n.º 13
0
        public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath indexPath)
        {
            var attributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
            var item       = DataSourceItems[(int)indexPath.Item];

            if (0 < ItemSize.Width && 0 < ItemSize.Height)
            {
                attributes.Frame = new CGRect(Offset.X, Offset.Y, ItemSize.Width - ContentEdgeInsets.Left - ContentEdgeInsets.Right, ItemSize.Height - ContentEdgeInsets.Top - ContentEdgeInsets.Bottom);
            }
            else if (ScrollDirection == UICollectionViewScrollDirection.Vertical)
            {
                attributes.Frame = new CGRect(ContentEdgeInsets.Left, Offset.Y, CollectionView.Bounds.Width - ContentEdgeInsets.Left - ContentEdgeInsets.Right, item.Height == null ? CollectionView.Bounds.Height : item.Height.Value);
            }
            else
            {
                attributes.Frame = new CGRect(Offset.X, ContentEdgeInsets.Top, item.Width == null? CollectionView.Bounds.Width : item.Width.Value, CollectionView.Bounds.Height - ContentEdgeInsets.Top - ContentEdgeInsets.Bottom);
            }


            return(attributes);
        }
Exemplo n.º 14
0
        public override void PrepareLayout()
        {
            if (_cache.Count > 0 || CollectionView == null)
            {
                return;
            }

            _contentHeight = 0;
            var columnWidth = (float)CollectionView.Frame.Width / ColumnCount;
            var xOffsets    = new List <float>();
            var yOffsets    = new List <float>();

            for (var i = 0; i < ColumnCount; i++)
            {
                xOffsets.Add(i * columnWidth);
                yOffsets.Add(0);
            }

            if (Header != null)
            {
                var indexPath = NSIndexPath.FromRowSection(0, 0);
                var frame     = new CGRect(0, 0, CollectionView.Frame.Width, Header.HeightRequest);

                var attrs = UICollectionViewLayoutAttributes.CreateForSupplementaryView(UICollectionElementKindSection.Header, indexPath);
                attrs.Frame = frame;
                _cache.Add(attrs);

                for (var i = 0; i < ColumnCount; i++)
                {
                    yOffsets[i] = (float)frame.Height;
                }
            }

            var column = 0;

            for (var r = 0; r < ItemsSource.Count; r++)
            {
                var isHeader = HeaderIndexes.Contains(r);

                var    width = columnWidth;
                double cellHeight;
                if (GetHeightForCellDelegate != null)
                {
                    cellHeight = GetHeightForCellDelegate(ItemsSource[r]);
                }
                else
                {
                    cellHeight = new Random().Next((int)MinCellHeight, (int)MaxCellHeight);
                }

                var y = yOffsets[column];
                if (isHeader) // HEADER
                {
                    width      = (float)CollectionView.Frame.Width;
                    cellHeight = HeaderTemplateHeight;
                    y          = (float)_contentHeight;
                    column     = 0;
                }

                var indexPath = NSIndexPath.FromRowSection(r, 0);
                var frame     = new CGRect(xOffsets[column], y, width, cellHeight);

                var attrs = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
                attrs.Frame = frame;

                _contentHeight = Math.Max((float)_contentHeight, (float)frame.GetMaxY());

                if (isHeader)
                {
                    for (var i = 0; i < ColumnCount; i++)
                    {
                        yOffsets[i] = (float)_contentHeight;
                    }

                    column = 0;
                }
                else
                {
                    yOffsets[column] = (float)(yOffsets[column] + cellHeight);
                    column           = column == ColumnCount - 1 ? 0 : column + 1;
                }
                _cache.Add(attrs);
            }
        }
Exemplo n.º 15
0
        public override void PrepareLayout()
        {
            base.PrepareLayout();

            // Get the number of sections
            var numberofSections = CollectionView.NumberOfSections();

            if (numberofSections == 0)
            {
                return;
            }

            // Reset collections
            _headersAttributes.Clear();
            _footersAttributes.Clear();
            _unionRects.Clear();
            _columnHeights.Clear();
            _allItemAttributes.Clear();
            _sectionItemAttributes.Clear();

            // Initialize column heights
            for (int n = 0; n < ColumnCount; n++)
            {
                _columnHeights.Add((nfloat)0);
            }

            // Process all sections
            nfloat top         = 0.0f;
            var    attributes  = new UICollectionViewLayoutAttributes();
            var    columnIndex = 0;

            for (nint section = 0; section < numberofSections; ++section)
            {
                // Calculate section specific metrics
                var minimumInterItemSpacing = (MinimumInterItemSpacingForSection == null) ? MinimumColumnSpacing :
                                              MinimumInterItemSpacingForSection(CollectionView, this, section);

                // Calculate widths
                var width     = CollectionView.Bounds.Width - SectionInset.Left - SectionInset.Right;
                var itemWidth = (nfloat)Math.Floor((width - ((ColumnCount - 1) * MinimumColumnSpacing)) / ColumnCount);

                // Calculate section header
                var heightHeader = (HeightForHeader == null) ? HeaderHeight :
                                   HeightForHeader(CollectionView, this, section);

                if (heightHeader > 0)
                {
                    attributes       = UICollectionViewLayoutAttributes.CreateForSupplementaryView(UICollectionElementKindSection.Header, NSIndexPath.FromRowSection(0, section));
                    attributes.Frame = new CGRect(0, top, CollectionView.Bounds.Width, heightHeader);
                    _headersAttributes.Add(section, attributes);
                    _allItemAttributes.Add(attributes);

                    top = attributes.Frame.GetMaxY();
                }

                top += SectionInset.Top;
                for (int n = 0; n < ColumnCount; n++)
                {
                    _columnHeights [n] = top;
                }

                // Calculate Section Items
                var itemCount = CollectionView.NumberOfItemsInSection(section);
                List <UICollectionViewLayoutAttributes> itemAttributes = new List <UICollectionViewLayoutAttributes> ();

                for (nint n = 0; n < itemCount; n++)
                {
                    var indexPath = NSIndexPath.FromRowSection(n, section);
                    columnIndex = NextColumnIndexForItem(n);
                    var    xOffset    = SectionInset.Left + (itemWidth + MinimumColumnSpacing) * (nfloat)columnIndex;
                    var    yOffset    = _columnHeights [columnIndex];
                    var    itemSize   = (SizeForItem == null) ? new CGSize(0, 0) : SizeForItem(CollectionView, this, indexPath);
                    nfloat itemHeight = 0.0f;

                    if (itemSize.Height > 0.0f && itemSize.Width > 0.0f)
                    {
                        itemHeight = (nfloat)Math.Floor(itemSize.Height * itemWidth / itemSize.Width);
                    }

                    attributes       = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
                    attributes.Frame = new CGRect(xOffset, yOffset, itemWidth, itemHeight);
                    itemAttributes.Add(attributes);
                    _allItemAttributes.Add(attributes);
                    _columnHeights [columnIndex] = attributes.Frame.GetMaxY() + MinimumInterItemSpacing;
                }
                _sectionItemAttributes.Add(itemAttributes);

                // Calculate Section Footer
                nfloat footerHeight = 0.0f;
                columnIndex  = LongestColumnIndex();
                top          = _columnHeights [columnIndex] - MinimumInterItemSpacing + SectionInset.Bottom;
                footerHeight = (HeightForFooter == null) ? FooterHeight : HeightForFooter(CollectionView, this, section);

                if (footerHeight > 0)
                {
                    attributes       = UICollectionViewLayoutAttributes.CreateForSupplementaryView(UICollectionElementKindSection.Footer, NSIndexPath.FromRowSection(0, section));
                    attributes.Frame = new CGRect(0, top, CollectionView.Bounds.Width, footerHeight);
                    _footersAttributes.Add(section, attributes);
                    _allItemAttributes.Add(attributes);
                    top = attributes.Frame.GetMaxY();
                }

                for (int n = 0; n < ColumnCount; n++)
                {
                    _columnHeights [n] = top;
                }
            }

            var i     = 0;
            var attrs = _allItemAttributes.Count;

            while (i < attrs)
            {
                var rect1 = _allItemAttributes [i].Frame;
                i = (int)Math.Min(i + _unionSize, attrs) - 1;
                var rect2 = _allItemAttributes [i].Frame;
                _unionRects.Add(CGRect.Union(rect1, rect2));
                i++;
            }
        }
        public override void PrepareLayout()
        {
            if (_cache.IsNullOrEmpty())
            {
                var cellSizes = new CGSize[CollectionView.NumberOfItemsInSection(0)];

                for (int index = 0; index < cellSizes.Length; index++)
                {
                    var indexPath = NSIndexPath.FromRowSection(index, 0);

                    var cellSize = Delegate?.SizeForCellAtIndexPath(CollectionView, indexPath) ?? CGSize.Empty;

                    cellSizes[index] = cellSize;
                }

                var column  = 0;
                var yOffset = new nfloat[NumberOfColumns];

                var supplementaryAttr = UICollectionViewLayoutAttributes.CreateForSupplementaryView(UICollectionElementKindSection.Header, NSIndexPath.FromRowSection(0, 0));
                supplementaryAttr.Frame = new CGRect(CGPoint.Empty, HeaderReferenceSize);
                _cache.Add(supplementaryAttr);

                //add begin Y offset to each column
                for (int i = 0; i < NumberOfColumns; i++)
                {
                    yOffset[i] = HeaderReferenceSize.Height == 0 ? 0 : HeaderReferenceSize.Height + MinimumLineSpacing / 2;
                }


                var previousCellPoint = CGPoint.Empty;

                for (int index = 0; index < CollectionView.NumberOfItemsInSection(0); index++)
                {
                    CGSize previousCellSize = index == 0 ? CGSize.Empty : cellSizes[index - 1];
                    CGSize currentCellSize  = cellSizes[index];

                    var width  = currentCellSize.Width + (MinimumInteritemSpacing * 2);
                    var height = currentCellSize.Height + MinimumLineSpacing;

                    //check that width of next cell in column [1; NumberOfColumns) does not go beyond the borders of content width
                    var previuosCellsWidth = previousCellPoint.X + previousCellSize.Width + MinimumInteritemSpacing;
                    if (column != 0 && previuosCellsWidth + width > ContentWidth)
                    {
                        //add Y offset to current column
                        yOffset[column] = yOffset[column] + height;

                        //switch column number to zero
                        column            = 0;
                        previousCellPoint = CGPoint.Empty;
                    }

                    //get cell real frame
                    var frame      = new CGRect(column == 0 ? 0 : previuosCellsWidth, yOffset[column], width, height + MinimumLineSpacing);
                    var insetFrame = frame.Inset(MinimumInteritemSpacing, MinimumLineSpacing);

                    //get cell atribute for frame
                    var indexPath  = NSIndexPath.FromRowSection(index, 0);
                    var attributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);
                    attributes.Frame = insetFrame;

                    //add attribute to cache
                    _cache.Add(attributes);

                    //update content height
                    _contentHeight = (nfloat)Math.Max(_contentHeight, frame.Bottom);

                    //add Y offset to column
                    yOffset[column] = yOffset[column] + height;

                    //save previous cell point
                    previousCellPoint = column >= (NumberOfColumns - 1) ? CGPoint.Empty : new CGPoint(insetFrame.X, insetFrame.Y);

                    //increment column number
                    column = column >= (NumberOfColumns - 1) ? 0 : ++column;
                }
            }
        }
        public override void PrepareLayout()
        {
            base.PrepareLayout();

            var sectionCount = CollectionView.NumberOfSections();

            if (sectionCount == 0)
            {
                return;
            }

            // Reset Cache
            _cachedAttributes.Clear();
            _contentBounds = new CGRect(CGPoint.Empty, CollectionView.Bounds.Size);

            var itemCount    = CollectionView.NumberOfItemsInSection(0);
            var currentIndex = 0;
            var itemStyle    = DetermineItemStyle(itemCount);
            var lastFrame    = CGRect.Empty;
            var cvWidth      = CollectionView.Bounds.Width;
            var cvHeight     = CollectionView.Bounds.Height;

            while (currentIndex < itemCount)
            {
                CGRect segmentFrame;
                var    segmentRects = new List <CGRect>();

                switch (itemStyle)
                {
                case MosaicStyle.FullWidth:
                    segmentFrame = new CGRect(0, lastFrame.GetMaxY() + 1, cvWidth, cvHeight);

                    segmentRects.Add(segmentFrame);
                    break;

                case MosaicStyle.HalfWidth:
                    segmentFrame = new CGRect(0, lastFrame.GetMaxY() + 1, cvWidth, cvHeight / 2);

                    var slices = segmentFrame.DividedIntegral((nfloat)0.5, CGRectEdge.MinXEdge);

                    segmentRects.Add(slices["First"]);
                    segmentRects.Add(slices["Second"]);

                    break;

                case MosaicStyle.TwoThirdsByOneThird:
                    segmentFrame = new CGRect(0, lastFrame.GetMaxY() + 1, cvWidth, cvHeight / 3);

                    var twoThirdsHorizontalSlices = segmentFrame.DividedIntegral((nfloat)(2.0 / 3.0), CGRectEdge.MinXEdge);
                    var twoThirdsVerticalSlices   = segmentFrame.DividedIntegral((nfloat)0.5, CGRectEdge.MinYEdge);

                    segmentRects.Add(twoThirdsHorizontalSlices["First"]);
                    segmentRects.Add(twoThirdsVerticalSlices["First"]);
                    segmentRects.Add(twoThirdsVerticalSlices["Second"]);
                    break;

                case MosaicStyle.OneThirdByTwoThirds:
                    segmentFrame = new CGRect(0, lastFrame.GetMaxY() + 1, cvWidth, cvHeight / 3);

                    var oneThirdHorizontalSlices = segmentFrame.DividedIntegral((nfloat)(1.0 / 3.0), CGRectEdge.MinXEdge);
                    var oneThirdVerticalSlices   = segmentFrame.DividedIntegral((nfloat)0.5, CGRectEdge.MinYEdge);

                    segmentRects.Add(oneThirdVerticalSlices["First"]);
                    segmentRects.Add(oneThirdVerticalSlices["Second"]);
                    segmentRects.Add(oneThirdHorizontalSlices["Second"]);
                    break;
                }

                // cache attributes.
                foreach (var rect in segmentRects)
                {
                    var indexPath  = NSIndexPath.FromRowSection(currentIndex, 0);
                    var attributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath);

                    attributes.Frame = rect;

                    _cachedAttributes.Add(attributes);
                    _contentBounds = _contentBounds.UnionWith(lastFrame);

                    currentIndex++;
                    lastFrame = rect;
                }

                // determine style for next segment
                switch (itemCount - currentIndex)
                {
                case 1:
                    itemStyle = MosaicStyle.FullWidth;
                    break;

                case 2:
                    itemStyle = MosaicStyle.HalfWidth;
                    break;

                default:
                    switch (itemStyle)
                    {
                    case MosaicStyle.FullWidth:
                        itemStyle = MosaicStyle.HalfWidth;
                        break;

                    case MosaicStyle.HalfWidth:
                        itemStyle = MosaicStyle.TwoThirdsByOneThird;
                        break;

                    case MosaicStyle.TwoThirdsByOneThird:
                        itemStyle = MosaicStyle.OneThirdByTwoThirds;
                        break;

                    case MosaicStyle.OneThirdByTwoThirds:
                        itemStyle = MosaicStyle.HalfWidth;
                        break;
                    }
                    break;
                }
            }
        }