UICollection View Flow Layout Vertical Align

后端 未结 10 2139
無奈伤痛
無奈伤痛 2021-02-03 21:45

By default, when you are using the flow layout in a collection view, cells are centered vertically. Is there a way to change this alignment ?

10条回答
  •  别那么骄傲
    2021-02-03 22:09

    @DongXu: Your solution worked for me too. Here is the Xamarin.iOS version if it:

    public class TopAlignedCollectionViewFlowLayout : UICollectionViewFlowLayout
    {
        public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CGRect rect)
        {
            if (base.LayoutAttributesForElementsInRect(rect) is UICollectionViewLayoutAttributes[] attrs)
            {
                // Find all the cells and group them together by the rows they appear on
                var cellsGroupedByRow = attrs
                    .Where(attr => attr.RepresentedElementCategory == UICollectionElementCategory.Cell)
                    // The default flow layout aligns cells in the middle of the row.
                    // Thus, cells with the same Y center point are in the same row.
                    // Convert to int, otherwise float values can be slighty different for cells on the same row and cause bugs.
                    .GroupBy(attr => Convert.ToInt32(attr.Frame.GetMidY()));
    
                foreach (var cellRowGroup in cellsGroupedByRow)
                {
                    TopAlignCellsOnSameLine(cellRowGroup.ToArray());
                }
    
                return attrs;
            }
    
            return null;
        }
    
        private static void TopAlignCellsOnSameLine(UICollectionViewLayoutAttributes[] cells)
        {
            // If only 1 cell in the row its already top aligned.
            if (cells.Length <= 1) return;
    
            // The tallest cell has the correct Y value for all the other cells in the row
            var tallestCell = cells.OrderByDescending(cell => cell.Frame.Height).First();
    
            var topOfRow = tallestCell.Frame.Y;
    
            foreach (var cell in cells)
            {
                if (cell.Frame.Y == topOfRow) continue;
    
                var frame = cell.Frame;
    
                frame.Y = topOfRow;
    
                cell.Frame = frame;
            }
        }
    }
    

提交回复
热议问题