UICollectionView设置列数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UICollectionView设置列数相关的知识,希望对你有一定的参考价值。

我刚开始学习UICollectionViews。我想知道是否有人知道如何指定集合视图中的列数。默认设置为3(iPhone /肖像)。我查看了文档,似乎无法找到简明的答案。

答案

CollectionViews非常强大,而且价格合理。很多,有很多选择。正如omz所说:

您可以通过多种方式更改列数

我建议实现<UICollectionViewDelegateFlowLayout>协议,让您可以访问以下方法,在这些方法中,您可以更好地控制UICollectionView的布局,而无需对其进行子类化:

  • collectionView:layout:insetForSectionAtIndex:
  • collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
  • collectionView:layout:minimumLineSpacingForSectionAtIndex:
  • collectionView:layout:referenceSizeForFooterInSection:
  • collectionView:layout:referenceSizeForHeaderInSection:
  • collectionView:layout:sizeForItemAtIndexPath:

此外,实现以下方法将强制您的UICollectionView在方向更改时更新它的布局:(假设您要为景观重新调整单元格的大小并使其延伸)

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                               duration:(NSTimeInterval)duration{

    [self.myCollectionView.collectionViewLayout invalidateLayout];
}

另外,这里有两个关于UICollectionViews的非常好的教程:

http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12

http://skeuo.com/uicollectionview-custom-layout-tutorial

另一答案

它是关于你想要绘制的布局。您可以创建从UICollectionViewFlowLayout继承的自定义类。目前没有任何直接的方法来设置列。如果要实现此类功能,则需要手动完成。您需要在自定义流布局类中处理它。

现在问题会出现在你怎么做的地方?如果您不想打扰细胞框架,您可以调整

 collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
 collectionView:layout:minimumLineSpacingForSectionAtIndex:

另一种方法是为您提供自己的细胞位置。通过覆盖下面的两个方法,这些方法将在布局形成期间调用。

  - (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
  - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path

UICollectionViewLayoutAttributes是一个处理单元格位置,框架,Zindex等的类

另一答案

这个答案适用于swift 3.0 - >

首先符合协议:

 UICollectionViewDelegateFlowLayout

然后添加这些方法:

    //this method is for the size of items      
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = collectionView.frame.width/3
        let height : CGFloat = 160.0
        return CGSize(width: width, height: height)
    }
    //these methods are to configure the spacing between items

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsetsMake(0,0,0,0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
另一答案

我只想附加Imanou Petit的回答#2。无论屏幕宽度如何,为了确保边距是精确的,我使用具有所需边距的迭代求解器和作为输入的列数。我还在其最终边距将与目标进行比较的位置添加了方向标记。

迭代求解器如下所示,返回cellWidth和margin。

private func iterativeCellSpacing(targetMargins : CGFloat,
                                  cellsPerRow : Int,
                                  isMinTarget : Bool) -> (CGFloat, CGFloat)
{
    var w : CGFloat = 0
    var m : CGFloat = targetMargins
    let cols : CGFloat = CGFloat(cellsPerRow)

    let numMargins : CGFloat = cols + 1.0
    let screenWidth : CGFloat = collectionView!.bounds.size.width


    var delta = CGFloat.greatestFiniteMagnitude
    while abs(delta) > 0.001
    {
        let totalMarginSpacing = numMargins * m
        let totalCellSpacing = screenWidth - totalMarginSpacing

        if (isMinTarget)
        {
            w = floor(totalCellSpacing / cols)
            m = ceil((screenWidth - cols * w) / numMargins)
        }
        else
        {
            w = ceil(totalCellSpacing / cols)
            m = floor((screenWidth - cols * w) / numMargins)
        }

        delta = screenWidth - w * CGFloat(cellsPerRow) - m * numMargins
    }

    return (w, m)
}

我称之为:

fileprivate var margin: CGFloat = 20
fileprivate var cellWidth : CGFloat = 80
fileprivate let cellsPerRow = 4

override func viewDidLoad()
{
    super.viewDidLoad()

    (cellWidth, margin) = iterativeCellSpacing(targetMargins: margin, cellsPerRow: 4, isMinTarget: true)
    ...
}

然后我将cellWidth和margin值应用于流布局,如下所示:

extension MyCollectionController : UICollectionViewDelegateFlowLayout

{func collectionView(_ collectionView:UICollectionView,layout collectionViewLayout:UICollectionViewLayout,sizeForItemAt indexPath:IndexPath) - > CGSize {return CGSize(width:cellWidth,height:cellWidth)}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    collectionView?.collectionViewLayout.invalidateLayout()
    super.viewWillTransition(to: size, with: coordinator)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
    return UIEdgeInsetsMake(margin, margin, margin, margin)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
{
    return margin
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
{
    return margin
}

}

希望这可以帮助。可能有一种更简单的方法来确保边距是准确的,但这是一种方法。此外,此代码尚未针对允许旋转收集视图的设备进行测试。

谢谢,

另一答案

完美的解决方案是使用UICollectionViewDelegateFlowLayout,但您可以轻松地计算单元格宽度并除以您想要的列数

棘手的是使宽度没有分数

(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

{
 CGFloat screenWidth = self.view.frame.size.width;
   CGFloat marginWidth = (screenWidth - collectionView.frame.size.width);


   CGFloat cellWith = (collectionView.frame.size.width - marginWidth )/3;
   cellWith= floorf(cellWith);




  CGSize retval = CGSizeMake(cellWith,cellWith);


  return retval;}
另一答案

我做了一个集合布局。

要使分隔符可见,请将集合视图的背景颜色设置为灰色。每节一行。

用途:

let layout = GridCollectionViewLayout()
layout.cellHeight = 50 // if not set, cellHeight = Collection.height/numberOfSections
layout.cellWidth = 50  // if not set, cellWidth = Collection.width/numberOfItems(inSection)
collectionView.collectionViewLayout = layout

布局:

import UIKit

class GridCollectionViewLayout: UICollectionViewLayout {


var cellWidth : CGFloat = 0
var cellHeight : CGFloat = 0
var seperator: CGFloat = 1

private var cache = [UICollectionViewLayoutAttributes]()



override func prepare() {

    guard let collectionView = self.collectionView else {
        return
    }

    self.cache.removeAll()



        let numberOfSections = collectionView.numberOfSections

        if cellHeight <= 0
        {
            cellHeight = (collectionView.bounds.height - seperator*CGFloat(numberOfSections-1))/CGFloat(numberOfSections)
        }

以上是关于UICollectionView设置列数的主要内容,如果未能解决你的问题,请参考以下文章

自定义UICollectionLayout布局 —— UIKit之学习UICollectionView记录一《瀑布流》

Apple Photos collectionview 捏缩放如何工作?

简单几行代码设置UIcollectionView的section底色

Swift几行代码设置UIcollectionView的section底色,圆角

如何将 Header 设置为 UICollectionView

UICollectionView 设置框架