如何在水平collectionview中设置不同的单元格高度和宽度

Posted

技术标签:

【中文标题】如何在水平collectionview中设置不同的单元格高度和宽度【英文标题】:How to set different height and width of cells in horizontal collectionview 【发布时间】:2016-12-20 05:41:38 【问题描述】:

我有一个水平集合视图,它一次显示 5 个单元格,我已经通过 sizeForItemAt 进行了调整:

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

        return CGSize(width: (self.numberCollectionView?.bounds.size.width)!/5 - 3, height: (self.numberCollectionView?.bounds.size.width)!/5 - 3 )
    

但是这 5 个单元格的宽度和高度会不同,并且有一个比例。所以 center 项目将占据整个尺寸的 40%,2nd3rd 项目将占据 20% 的尺寸,而 >1st5th 将占大小的 10%。根据这个比率,项目大小会在 scroll 上发生变化。这些项目都是标签

编辑: 在我的情况下,与建议的问题和 *** 中的其他问题不同,只有一行,我有自定义 UICollectionViewFlowLayout 来处理单元格滚动

【问题讨论】:

How Can I Animate the Size of A UICollectionViewCell on Scroll so the middle one is largest?的可能重复 那个问题甚至没有正确答案 根据CGSize中的返回值,所有单元格将是完美的正方形,一次只显示5个提供单元格的项目间距是 3。 是的,但我不知道如何将可见中心元素的大小更改为整个宽度的 40% @Fay007 您可以根据您的 indexpath 设置所有单元格大小就像在此方法中您可以检查 indexpath.row == 0 然后返回此 【参考方案1】:

UICollectionViewFlowLayout 处理单元格滚动:

class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout 

    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint 
        var offsetAdjustment = CGFloat.greatestFiniteMagnitude
        let horizontalOffset = proposedContentOffset.x
        let targetRect = CGRect(x: proposedContentOffset.x, y: 0, width: self.collectionView!.bounds.size.width, height: self.collectionView!.bounds.size.height)

        for layoutAttributes in super.layoutAttributesForElements(in: targetRect)! 
            let itemOffset = layoutAttributes.frame.origin.x
            if (abs(itemOffset - horizontalOffset) < abs(offsetAdjustment)) 
                offsetAdjustment = itemOffset - horizontalOffset
            
        

        return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
    


然后找到CollectionView的中心单元格:

private func findCenterIndex() -> Int 
        let center = self.view.convert(numberCollectionView.center, to: self.numberCollectionView)
        let row = numberCollectionView!.indexPathForItem(at: center)?.row


        guard let index = row else 

            return 0
        

        self.rating = index

        return index

    

scrollViewDidScrolltransformed 单元格下:

func scrollViewDidScroll(_ scrollView: UIScrollView) 


            transformCell()

    



    private func transformCell() 


        let row =  findCenterIndex()

        var offset : Float = 0.0

        for cell in numberCollectionView.visibleCells as! [VotingCell] 

            if row == numberCollectionView.indexPath(for: cell)?.row 

                offset = 1.1
                cell.label.font = UIFont.boldSystemFont(ofSize: 28.0)
                cell.label.textColor = UIColor.black
                cell.alpha = 1.0
                cell.label.textAlignment = .center
            
            else if row == (numberCollectionView.indexPath(for: cell)?.row)! + 1 || row == (numberCollectionView.indexPath(for: cell)?.row)! - 1
            
                offset = 0.8
                cell.label.font = UIFont(name: cell.label.font.fontName, size: 26.0)
                cell.label.textColor = UIColor.gray
                cell.alpha = 0.8
                cell.label.textAlignment = .center

            
            else if row == (numberCollectionView.indexPath(for: cell)?.row)! + 2 || row == (numberCollectionView.indexPath(for: cell)?.row)! - 2 

                offset = 0.7
                cell.label.font = UIFont(name: cell.label.font.fontName, size: 20.0)
                cell.label.textColor = UIColor.gray
                cell.alpha = 0.8
                cell.label.textAlignment = .center
            
            else
            
                offset = 0.00

            


            cell.transform = CGAffineTransform.identity
            cell.transform = CGAffineTransform(scaleX: CGFloat(offset), y: CGFloat(offset))

        
    

也从viewDidLayoutSubviews 调用transformCell() 进行初始加载。

【讨论】:

我无法理解您代码中的两点。什么来自 [VotingCell] 和 self.rating ?

以上是关于如何在水平collectionview中设置不同的单元格高度和宽度的主要内容,如果未能解决你的问题,请参考以下文章

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

如何在 collectionView 单元格中设置 NSLayoutConstraint 常量?

如何仅为一个 indexPath.row 项目在 CollectionView 单元格中设置动画?

如何在 Swift 4 中设置从 collectionView 底部到 Input Accessory View 顶部的约束

Swift - 如何在水平 StackView 中设置可变数量按钮之间的间距?

在 UICollectionViewCell 中设置 UILabel