Exemplo n.º 1
0
        private void LayoutSectionHeader(Dictionary <string, LayoutInfo> layoutInfos, int section, ref CGRect frame)
        {
            if (ScrollDirection == ListViewBaseScrollDirection.Horizontal)
            {
                throw new NotImplementedException("The section header for a horizontal listview is not implemented.");
            }

            var createLayoutInfo = layoutInfos != null;

            if (section > 0)
            {
                frame.Y += IntersectionSpacing;
            }

            var sectionHeaderSize = GetSectionHeaderSize();

            frame.Height = sectionHeaderSize.Height;

            if (createLayoutInfo)
            {
                var sectionHeaderLayoutInfo = layoutInfos.FindOrCreate(ListViewBase.ListViewSectionHeaderElementKind, () => new LayoutInfo());

                //indexPath acts to uniquely identify this instance of ListViewSectionHeaderElementKind (one per section)
                var indexPath        = NSIndexPath.FromRowSection(0, section);
                var layoutAttributes = UICollectionViewLayoutAttributes.
                                       CreateForSupplementaryView <UICollectionViewLayoutAttributes>(ListViewBase.ListViewSectionHeaderElementKindNS, indexPath);
                layoutAttributes.Frame             = new CGRect(Margin.Left, frame.Y, frame.Width, sectionHeaderSize.Height);
                sectionHeaderLayoutInfo[indexPath] = layoutAttributes;
            }

            frame.Y += frame.Height + LineSpacing;
        }
Exemplo n.º 2
0
        public override UICollectionViewLayoutAttributes LayoutAttributesForSupplementaryView(NSString kind, NSIndexPath indexPath)
        {
            var attrs = UICollectionViewLayoutAttributes.CreateForSupplementaryView(kind, indexPath);

            attrs.Frame = new CGRect(0, 0, CollectionView.Frame.Width, Header.HeightRequest);
            return(attrs);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Adjusts the size of the frame by calculating the required space of the footer.
        /// </summary>
        private void LayoutFooter(Dictionary <string, LayoutInfo> layoutInfos, ref CGRect frame)
        {
            if (ScrollDirection == ListViewBaseScrollDirection.Horizontal)
            {
                throw new NotImplementedException("The footer for an horizontal listview is not implemented.");
            }

            var createLayoutInfo = layoutInfos != null;

            var footerSize = GetFooterSize();

            frame.Height = footerSize.Height;

            if (createLayoutInfo)
            {
                var footerLayoutInfo = new LayoutInfo();
                var indexPath        = NSIndexPath.FromRowSection(0, 0);

                var layoutAttributes = UICollectionViewLayoutAttributes.CreateForSupplementaryView <UICollectionViewLayoutAttributes>(ListViewBase.ListViewFooterElementKindNS, indexPath);
                layoutAttributes.Frame      = new CGRect(Margin.Left, frame.Y, frame.Width, footerSize.Height);
                footerLayoutInfo[indexPath] = layoutAttributes;
                layoutInfos[ListViewBase.ListViewFooterElementKind] = footerLayoutInfo;
            }

            frame.Y += frame.Height + LineSpacing;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Adjusts the size of the frame by calculating the required space of the header.
        /// </summary>
        private void LayoutHeader(Dictionary <string, LayoutInfo> layoutInfos, ref CGRect frame)
        {
            if (ScrollDirection == ListViewBaseScrollDirection.Horizontal)
            {
                throw new NotImplementedException("The header for an horizontal listview is not implemented.");
            }

            var createLayoutInfo = layoutInfos != null;

            var headerSize = GetHeaderSize();

            frame.Height = headerSize.Height;

            if (createLayoutInfo)
            {
                var headerLayoutInfo = new LayoutInfo();
                //"It is up to you to decide how to use the indexPath parameter to identify a given supplementary view. Typically, you use the elementKind parameter to identify the type
                //of the supplementary view and the indexPath information to distinguish between different instances of that view."
                //https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewLayoutAttributes_class/#//apple_ref/occ/clm/UICollectionViewLayoutAttributes/layoutAttributesForSupplementaryViewOfKind:withIndexPath:
                var indexPath = NSIndexPath.FromRowSection(0, 0);

                var layoutAttributes = UICollectionViewLayoutAttributes.CreateForSupplementaryView <UICollectionViewLayoutAttributes>(ListViewBase.ListViewHeaderElementKindNS, indexPath);
                layoutAttributes.Frame      = new CGRect(Margin.Left, frame.Y, frame.Width, headerSize.Height);
                headerLayoutInfo[indexPath] = layoutAttributes;
                layoutInfos[ListViewBase.ListViewHeaderElementKind] = headerLayoutInfo;
            }

            frame.Y += frame.Height + LineSpacing;
        }
Exemplo n.º 5
0
        private void CreateSectionHeaderLayoutInfo(Dictionary <NSIndexPath, UICollectionViewLayoutAttributes> headerLayoutInfo, int section, CGRect sectionHeaderFrame)
        {
            var indexPath        = GetNSIndexPathFromRowSection(0, section);
            var layoutAttributes = UICollectionViewLayoutAttributes
                                   .CreateForSupplementaryView <UICollectionViewLayoutAttributes>(ListViewBase.ListViewSectionHeaderElementKindNS, indexPath);

            layoutAttributes.Frame       = sectionHeaderFrame;
            headerLayoutInfo[indexPath]  = layoutAttributes;
            _inlineHeaderFrames[section] = sectionHeaderFrame;
        }
        public override UICollectionViewLayoutAttributes LayoutAttributesForSupplementaryView(NSString kind, NSIndexPath indexPath)
        {
            if (Forms.IsiOS11OrNewer)
            {
                return(base.LayoutAttributesForSupplementaryView(kind, indexPath));
            }

            // iOS 10 and lower doesn't create these and will throw an exception in GetViewForSupplementaryElement
            // without them, so we need to do it manually here
            return(UICollectionViewLayoutAttributes.CreateForSupplementaryView(kind, indexPath));
        }
Exemplo n.º 7
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.º 8
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;
                }
            }
        }