Collectionview 单元后的间距

Posted

技术标签:

【中文标题】Collectionview 单元后的间距【英文标题】:Spacing after Collectionview Cell 【发布时间】:2018-12-05 09:06:14 【问题描述】:

我想创建一个像图片一样的 UICollectionview。在这里,我有 18 个正方形。 Collection 视图的宽度是正方形宽度的 6 倍和三个边框线的宽度。同样高度也是正方形高度的 3 倍和两个边框线的添加。

在 collectionView 中,我如何在图片中添加前面以及单元格之间的边界线。

【问题讨论】:

为什么选择收藏视图。有没有重用机制?如果是,则发布完整的用户界面 【参考方案1】:

输出

您可以从UICollectionViewLayout获得以上设计布局。

三个文件: 1. SquareViewController 2. SquareCollectionViewCell 3.方形布局

SquareViewController----

class SquareViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource 

// CONSTRAINTS: top 20, left 0, right 0, height 100.
@IBOutlet weak var squareCollectionVw: UICollectionView!

// SET squareCollectionVw HEIGHT CONSTRAINT OUTLET
@IBOutlet weak var collectionVwHeightConst: NSLayoutConstraint!

override func viewDidLoad() 
    super.viewDidLoad()

    collectionVwHeightConst.constant = (UIScreen.main.bounds.width / 6) * 3 + 1
    squareCollectionVw.backgroundColor = UIColor.darkGray

    // Do any additional setup after loading the view.

func numberOfSections(in collectionView: UICollectionView) -> Int 

    return 1


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 

    return 18


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "square", for: indexPath) as! SquareCollectionViewCell

    cell.backgroundColor = UIColor.white
    cell.layer.borderColor = UIColor.lightGray.cgColor
    cell.layer.borderWidth = 1.0

    return cell


SquareCollectionViewCell

class SquareCollectionViewCell: UICollectionViewCell 


SquareLayout [UICollectionViewLayout]

class Square: UICollectionViewLayout 

    var CELL_HEIGHT = 0.0
    var CELL_WIDTH = 0.0

    var portrait_Ypos : Double = 0.0
    var portrait_Xpos : Double = 0.0
    var contentSize = CGSize.zero

    var cellAttrsDictionary = Dictionary<IndexPath, UICollectionViewLayoutAttributes>()

    override var collectionViewContentSize : CGSize 
        return self.contentSize
    

    override func prepare() 

        CELL_WIDTH = (Double(UIScreen.main.bounds.width) / 6) - 0.5
        CELL_HEIGHT = CELL_WIDTH


        if let sectionCount = collectionView?.numberOfSections, sectionCount > 0 

            for section in 0...sectionCount-1 

                if let rowCount = collectionView?.numberOfItems(inSection: section), rowCount > 0 

                    for item in 0...rowCount-1 

                        let cellIndex = IndexPath(item: item, section: section)

                        if item <= 5
                        
                            portrait_Ypos = 1

                            if item == 0
                            

                                portrait_Xpos = 1
                            
                            else
                            

                                if item == 3
                                

                                    portrait_Xpos = portrait_Xpos + CELL_WIDTH + 1
                                
                                else
                                

                                    portrait_Xpos = portrait_Xpos + CELL_WIDTH
                                

                            
                        
                        else
                        
                            if item == 6
                            
                                portrait_Ypos = 1 + CELL_HEIGHT
                                portrait_Xpos = 1
                            
                            else
                            
                                if item % 6 == 0
                                
                                    portrait_Ypos = portrait_Ypos + CELL_HEIGHT
                                    portrait_Xpos = 1
                                
                                else
                                
                                    if item % 6 == 3
                                    
                                        portrait_Xpos = portrait_Xpos + CELL_WIDTH + 1
                                    
                                    else
                                    
                                        portrait_Xpos = portrait_Xpos + CELL_WIDTH
                                    

                                
                            


                        

                        let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex)
                        cellAttributes.frame = CGRect(x: portrait_Xpos, y: portrait_Ypos, width: CELL_WIDTH, height: CELL_HEIGHT)

                        if section == 0 && item == 0 
                            cellAttributes.zIndex = 4
                         else if section == 0 
                            cellAttributes.zIndex = 3
                         else if item == 0 
                            cellAttributes.zIndex = 2
                         else 
                            cellAttributes.zIndex = 1
                        
                        cellAttrsDictionary[cellIndex] = cellAttributes

                    

                

            
        

        let contentWidth = UIScreen.main.bounds.width
        let contentHeight = CGFloat(portrait_Ypos) + CGFloat(CELL_HEIGHT)
        self.contentSize = CGSize(width: contentWidth, height: contentHeight)

        print("sPort.contentSize     ", self.contentSize)
    

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? 

        var attributesInRect = [UICollectionViewLayoutAttributes]()

        for cellAttributes in cellAttrsDictionary.values 
            if rect.intersects(cellAttributes.frame) 

                attributesInRect.append(cellAttributes)
            
        

        return attributesInRect
    

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? 

        return cellAttrsDictionary[indexPath]!

    

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool 
        return true
    

在 UICollectionView 中嵌入 UICollectionViewLayout:

选择squareCollectionVw,点击Attributes Inspector

    LayoutFlow 更改为 Custom

    Class as SquareLayout [对我来说,Square]

【讨论】:

如果您对此答案感到满意,请点赞并打勾。这对我们的 SO 追随者很有用【参考方案2】:

你可以简单地在你的 UICollectionView 和方法 cellForItem 中放置两个 UICollectionViewCell,里面有九个方块

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as! CustomCell

    cell.layer.borderWidth = 2
    cell.layer.borderColor = .black

    return cell

【讨论】:

【参考方案3】:

在我看来,您必须创建 2 个相同的单元格并在 UICollectionViewFlowLayoutDelegate 中将其配置为每个单元格宽度为 screen.width / 2 并为这两个单元格设置边框。在部分边框中,您可能需要使用图层(CALayer)以使其 4 边相等

【讨论】:

【参考方案4】:

用于在单元格之间添加空间

假设 UICollectionView 的一行中有 2 个单元格

例如:

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

        let width = (self.view.frame.size.width - 15) / 2.0 //total view width and 15 space between each cell
        let height = CGFloat(70.0) //Height is 70. (you can take same as width also)
        return CGSize(width: width, height: height)
    

这将帮助您在单元格之间添加空间。

用于在单元格之间添加边框

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionCell
    cell.layer.borderWidth = 1.0
    cell.layer.borderColor = UIColor.black


【讨论】:

以上是关于Collectionview 单元后的间距的主要内容,如果未能解决你的问题,请参考以下文章

Collectionview固定单元格间距

当单元格具有动态宽度时,CollectionView 中的间距不正确?

iOS UICollectionViewCell

Swift - 在CollectionView中设置不同宽度的单元格之间的固定间距

iOS - 如何使用自定大小的 CollectionView 单元格设置锚点以调整换行符的间距

Swift 3 collectionView 如何设置间距。