Ios CollectionView不带任何库的不同大小

Ios CollectionView不带任何库的不同大小,ios,swift,Ios,Swift,我正在尝试设计一个集合视图,它的布局会发生变化,如所附图像所示。如果有人对此设计有想法,请提供帮助 提前谢谢 我需要这种类型的布局,以便在没有任何库的情况下查看收藏 您需要创建UICollectionViewLayout的子类,并需要 重写准备方法 计算UICollectionViewLayoutAttribute的框架并将其存储在 缓存字典 实现layoutAttributesForElements和layoutAttributesForItem 方法使用缓存字典 以下是代码,请检查: i

我正在尝试设计一个集合视图,它的布局会发生变化,如所附图像所示。如果有人对此设计有想法,请提供帮助

提前谢谢

我需要这种类型的布局,以便在没有任何库的情况下查看收藏
  • 您需要创建UICollectionViewLayout的子类,并需要 重写准备方法

  • 计算UICollectionViewLayoutAttribute的框架并将其存储在 缓存字典

  • 实现layoutAttributesForElements和layoutAttributesForItem 方法使用缓存字典

  • 以下是代码,请检查:

    import UIKit
    
    class MJCollectionLayout: UICollectionViewLayout {
        fileprivate var cache = [IndexPath: UICollectionViewLayoutAttributes]()
        fileprivate var cellPadding: CGFloat = 1
        fileprivate var contentHeight: CGFloat = 0
        var oldBound: CGRect!
        fileprivate var contentWidth: CGFloat {
            guard let collectionView = collectionView else {
                return 0
            }
            let insets = collectionView.contentInset
            return collectionView.bounds.width - (insets.left + insets.right)
        }
    
        override var collectionViewContentSize: CGSize {
            return CGSize(width: contentWidth, height: contentHeight)
        }
    
        override func prepare() {
            super.prepare()
            contentHeight = 0
            cache.removeAll(keepingCapacity: true)
            guard cache.isEmpty == true, let collectionView = collectionView else {
                return
            }
            if collectionView.numberOfSections == 0 {
                return
            }
            oldBound = self.collectionView?.bounds
            for item in 0 ..< collectionView.numberOfItems(inSection: 0) {
                let indexPath = IndexPath(item: item, section: 0)
                let cellSize = self.getCellSize(index: item)
                let origin = self.getOrigin(index: item)
                let frame = CGRect(origin: origin, size: cellSize)
                let insetFrame = frame.insetBy(dx: cellPadding, dy: cellPadding)
                let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
                attributes.frame = insetFrame
                cache[indexPath] = (attributes)
                contentHeight = max(contentHeight, frame.maxY)
            }
        }
    
        func getCellSize(index: Int) -> CGSize {
            let col = index % 6
            let width = contentWidth / 2.0
            if col == 2  {
                return CGSize.init(width: 2 * width, height: width)
            }
            if col == 4 {
                return CGSize.init(width:  width, height: 2 * width)
            }
            return CGSize.init(width: width, height: width)
        }
    
        func getOrigin(index: Int) -> CGPoint {
            let col = index % 6
            let multiplayer = index / 6
            let width = contentWidth / 2.0
            var y: CGFloat = 0.0
            var x: CGFloat = 0.0
            if col == 0 || col == 1 {
                y = CGFloat(multiplayer) * (8.0 * width) + 0
            }
            if col == 2 {
                y = CGFloat(multiplayer) * (8.0 * width) + width
            }
            if col == 3 || col == 4  {
                y = CGFloat(multiplayer) * (8.0 * width) + (2.0 * width)
            }
            if col == 5 {
                 y = CGFloat(multiplayer) * (8.0 * width) + (3.0 * width)
            }
            if col == 0 || col == 2 || col == 3 || col == 5 {
                x = 0.0
            }
            if  col == 1 || col == 4 {
                x = width
            }
    
            return CGPoint(x: x, y: y)
        }
    
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            var visibleLayoutAttributes = [UICollectionViewLayoutAttributes]()
            // Loop through the cache and look for items in the rect
            visibleLayoutAttributes = cache.values.filter({ (attributes) -> Bool in
                return attributes.frame.intersects(rect)
            })
            print(visibleLayoutAttributes)
            return visibleLayoutAttributes
        }
    
        override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
            // print(cache[indexPath.item])
            return cache[indexPath]
        }
    
        override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
            if newBounds.width != oldBound?.width {
                return true
            }
            return false
        }
    }
    
    导入UIKit
    MJ类CollectionLayout:UICollectionViewLayout{
    fileprivate变量缓存=[IndexPath:UICollectionViewLayoutAttribute]()
    fileprivate变量cellPadding:CGFloat=1
    fileprivate var contentHeight:CGFloat=0
    var oldbund:CGRect!
    fileprivate var contentWidth:CGFloat{
    guard let collectionView=collectionView else{
    返回0
    }
    let insets=collectionView.contentInset
    return collectionView.bounds.width-(insets.left+insets.right)
    }
    覆盖变量collectionViewContentSize:CGSize{
    返回CGSize(宽度:contentWidth,高度:contentHeight)
    }
    重写func prepare(){
    超级准备
    contentHeight=0
    cache.removeAll(保留容量:true)
    guard cache.isEmpty==true,让collectionView=collectionView else{
    回来
    }
    如果collectionView.numberOfSections==0{
    回来
    }
    oldbund=self.collectionView?.bounds
    对于0..CGSize{
    设col=索引%6
    let width=contentWidth/2.0
    如果col==2{
    返回CGSize.init(宽度:2*width,高度:width)
    }
    如果col==4{
    返回CGSize.init(宽度:宽度,高度:2*width)
    }
    返回CGSize.init(宽度:宽度,高度:宽度)
    }
    func getOrigin(索引:Int)->CGPoint{
    设col=索引%6
    让多人游戏=索引/6
    let width=contentWidth/2.0
    变量y:CGFloat=0.0
    变量x:CGFloat=0.0
    如果col==0 | | col==1{
    y=CGFloat(多人游戏)*(8.0*宽度)+0
    }
    如果col==2{
    y=CGFloat(多人游戏)*(8.0*宽度)+宽度
    }
    如果col==3 | | col==4{
    y=CGFloat(多人游戏)*(8.0*宽度)+(2.0*宽度)
    }
    如果col==5{
    y=CGFloat(多人游戏)*(8.0*宽度)+(3.0*宽度)
    }
    如果col==0 | | col==2 | | col==3 | | col==5{
    x=0.0
    }
    如果col==1 | | col==4{
    x=宽度
    }
    返回点(x:x,y:y)
    }
    是否覆盖func layoutAttributesForElements(在rect:CGRect中)->[UICollectionViewLayoutAttributes]{
    变量VisibleLayoutAttribute=[UICollectionViewLayoutAttribute]()
    //循环缓存并在rect中查找项
    visibleLayoutAttributes=cache.values.filter({(属性)->Bool-in
    返回attributes.frame.intersects(rect)
    })
    打印(VisibleLayoutAttribute)
    返回VisibleLayoutAttribute
    }
    重写func layoutAttributesForItem(在indexPath:indexPath)->UICollectionViewLayoutAttributes{
    //打印(缓存[indexath.item])
    返回缓存[indexPath]
    }
    覆盖函数应验证布局(对于边界新边界:CGRect)->Bool{
    如果newBounds.width!=oldbund?.width{
    返回真值
    }
    返回错误
    }
    }
    
    ?使用自己的规则创建自己的
    UICollectionViewFlowLayout
    。UICollectionViewFlowLayout对于这种布局的纠结已经足够了