当前位置: 首页 > 知识库问答 >
问题:

如何居中对齐UICollectionView的单元格?

孙京
2023-03-14

我目前正在使用UICollectionView作为用户交互界面网格,它运行良好。但是,我想启用水平滚动。网格每页支持8个项目,当项目总数为4个时,这是启用水平滚动方向时应该如何排列项目:

0 0 x x
0 0 x x

这里0 -

有没有办法让它们像这样居中对齐:

x 0 0 x
x 0 0 x

这样内容看起来更干净?

下面的安排也可能是我期待的一个解决方案。

0 0 0 0
x x x x

共有3个答案

钮出野
2023-03-14

这里的顶级解决方案对我来说是开箱即用的,所以我想到了这个解决方案,它应该适用于任何具有流程布局且只有一个部分的水平滚动集合视图:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
    {
    // Add inset to the collection view if there are not enough cells to fill the width.
    CGFloat cellSpacing = ((UICollectionViewFlowLayout *) collectionViewLayout).minimumLineSpacing;
    CGFloat cellWidth = ((UICollectionViewFlowLayout *) collectionViewLayout).itemSize.width;
    NSInteger cellCount = [collectionView numberOfItemsInSection:section];
    CGFloat inset = (collectionView.bounds.size.width - (cellCount * cellWidth) - ((cellCount - 1)*cellSpacing)) * 0.5;
    inset = MAX(inset, 0.0);
    return UIEdgeInsetsMake(0.0, inset, 0.0, 0.0);
    }
饶德本
2023-03-14

我认为你可以通过实现下面这样的东西来实现单行外观:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 100, 0, 0);
}

您将不得不摆弄这个数字,以弄清楚如何将内容强制转换成一行。第一个0是顶边参数,如果你想让内容在屏幕上垂直居中,你也可以调整它。

闻人英韶
2023-03-14

对于那些像我一样寻找中心对齐,动态宽度集合视图单元格解决方案的人,我最终修改了Angel对左对齐版本的答案,为UICollectionViewFlowLayout创建了一个居中对齐的子类。

// NOTE: Doesn't work for horizontal layout!
class CenterAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let superAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
        // Copy each item to prevent "UICollectionViewFlowLayout has cached frame mismatch" warning
        guard let attributes = NSArray(array: superAttributes, copyItems: true) as? [UICollectionViewLayoutAttributes] else { return nil }
        
        // Constants
        let leftPadding: CGFloat = 8
        let interItemSpacing = minimumInteritemSpacing
        
        // Tracking values
        var leftMargin: CGFloat = leftPadding // Modified to determine origin.x for each item
        var maxY: CGFloat = -1.0 // Modified to determine origin.y for each item
        var rowSizes: [[CGFloat]] = [] // Tracks the starting and ending x-values for the first and last item in the row
        var currentRow: Int = 0 // Tracks the current row
        attributes.forEach { layoutAttribute in
            
            // Each layoutAttribute represents its own item
            if layoutAttribute.frame.origin.y >= maxY {
                
                // This layoutAttribute represents the left-most item in the row
                leftMargin = leftPadding
                
                // Register its origin.x in rowSizes for use later
                if rowSizes.count == 0 {
                    // Add to first row
                    rowSizes = [[leftMargin, 0]]
                } else {
                    // Append a new row
                    rowSizes.append([leftMargin, 0])
                    currentRow += 1
                }
            }
            
            layoutAttribute.frame.origin.x = leftMargin
            
            leftMargin += layoutAttribute.frame.width + interItemSpacing
            maxY = max(layoutAttribute.frame.maxY, maxY)
            
            // Add right-most x value for last item in the row
            rowSizes[currentRow][1] = leftMargin - interItemSpacing
        }
        
        // At this point, all cells are left aligned
        // Reset tracking values and add extra left padding to center align entire row
        leftMargin = leftPadding
        maxY = -1.0
        currentRow = 0
        attributes.forEach { layoutAttribute in
            
            // Each layoutAttribute is its own item
            if layoutAttribute.frame.origin.y >= maxY {
                
                // This layoutAttribute represents the left-most item in the row
                leftMargin = leftPadding
                
                // Need to bump it up by an appended margin
                let rowWidth = rowSizes[currentRow][1] - rowSizes[currentRow][0] // last.x - first.x
                let appendedMargin = (collectionView!.frame.width - leftPadding  - rowWidth - leftPadding) / 2
                leftMargin += appendedMargin
                
                currentRow += 1
            }
            
            layoutAttribute.frame.origin.x = leftMargin
            
            leftMargin += layoutAttribute.frame.width + interItemSpacing
            maxY = max(layoutAttribute.frame.maxY, maxY)
        }
        
        return attributes
    }
}
 类似资料:
  • 问题内容: 我已经做过一些研究,但是找不到关于如何水平放置UICollectionView中的单元格的代码示例。 而不是第一个单元格像这样的 X00 ,我希望它像这样的 0X0 。有什么办法可以做到这一点? 编辑: 可视化我想要的东西: 当CollectionView中只有一个元素时,我需要它看起来像版本B。当我获得多个元素时,它应该类似于版本A,但具有更多元素。 目前,当我只有1个元素时,它看起

  • 问题内容: 我需要居中对齐水平菜单。 我尝试了各种解决方案,包括/ / 等等的组合,但是没有成功。 这是我的代码: 更新 我知道如何中心对齐的内部。可以使用Sarfraz的建议来完成。但是列表项仍然浮动在内。 我需要Java语言来完成此操作吗? 问题答案: 前提很简单,基本上只涉及一个无宽度的浮动包装,该浮动包装浮动到左侧,然后从屏幕上移到左侧的宽度位置。左:-50%。接下来,将嵌套的内部元素反转

  • 我有以下代码将图像放在比图像大小更宽的表格单元格中心。我使用了文本中心和对齐中产阶级,但没有任何效果。图像仍然在单元格的左侧。我是引导新手,所以不知道任何其他技术。

  • 问题内容: 我想有A B和C中间对齐。 我如何才能D完全右移? 问题答案: 以下是实现此布局的五个选项: CSS定位 带有不可见DOM元素的Flexbox 带有不可见伪元素的Flexbox Flexbox与 flex: 1 CSS网格布局 方法1:CSS定位属性 应用于容器。 应用于项目D。 现在,此项目已完全放置在flex容器中。 更具体地说,项目D从文档流中删除,但停留在最接近的祖先的范围内。

  • 问题内容: 我有一个 带有Title 的 JFrame 。我希望 标题居中对齐 ,以便它出现在 JFrame标题 的 中间 。 谢谢。 问题答案: 考虑将标题左对齐…但是…这将使您靠近中心。对于可调整大小的框架,您需要在调整大小时重写标题。

  • 问题内容: 我不知道如何对齐JTable中单元格的值。 例如,Jtable显示姓名工资X.先生100000.50 XXXX 234.34 YYYy 1205.50 我想以以下格式对齐“薪水”。 如何在JTable上方对齐 问题答案: 无需为此创建自定义类,只需使用默认渲染器即可: 或者更好的方法是在表中实际存储Double值,然后使用适当的数字渲染器,数字渲染器将自动右对齐。然后,您可以使用表格格