chenzhao

  • java
  • iOS
  • IT
知识积累
不积跬步无以至千里
  1. 首页
  2. iOS
  3. 正文

UICollectionViewFlowLayout最大间距设置

2016年 8月 29日 82点热度 0人点赞 0条评论
//
//  DanceTeamSearchLayout.swift
//  boosjdance
//
//  Created by boosj on 16/8/29.
//  Copyright © 2016年 cz. All rights reserved.
//
//swift3 
import UIKit
/// 舞队 搜索记录的layout
class DanceTeamSearchLayout: UICollectionViewFlowLayout {
    //我们想设置的最大间距,可根据需要改
    //var maximumSpacing:CGFloat = 10
    /**
     重写当前方法 实现控制item最大间距
     
     - parameter rect: rect 绘图范围
     
     - returns: item属性数组
     */
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributes = super.layoutAttributesForElements(in: rect)
        if attributes != nil{
            for i in 0 ..< attributes!.count{
                if i == 0{
                   let current = attributes![i]
                    var frame = current.frame
                    frame.origin.x = 10
                    current.frame = frame
                    continue
                }
                //当前attributes
                let current = attributes![i]
                //上一个attributes
                let prevLayoutAttributes = attributes![ (i - 1)]
                        //前一个cell的最右边
                let origin = prevLayoutAttributes.frame.maxX
               // var yOffset = current.frame.origin.y
                //如果当前一个cell的最右边加上我们想要的间距加上当前cell的宽度依然在contentSize中,我们改变当前cell的原点位置
                //不加这个判断的后果是,UICollectionView只显示一行,原因是下面所有cell的x值都被加到第一行最后一个元素的后面了
                // self.minimumInteritemSpacing 列间距
                if (origin + self.minimumInteritemSpacing + current.frame.size.width)<self.collectionViewContentSize.width{
                    var frame = current.frame
                    frame.origin.x = origin + self.minimumInteritemSpacing
                    current.frame = frame
                    
                }else{
                    var frame = current.frame
                    frame.origin.x = self.sectionInset.left // 边缘的预留宽度
                   // frame.origin.y = yOffset + frame.height + maximumSpacing
                    current.frame = frame
                }
               // printLog("cell测试frame: \(current.frame)")
            }
        }
        return attributes
    }
    
    /*
     如果我们的布局是会时刻变化的, 需要在滚动的过程中重新布局 , 那么我们需要
     设置这个方法的返回值为true, 默认为false
     * 当返回值为true的时候会将collectionView的layout设置为invalidated,
     将会使collectionView重新调用上面的prepareLayout()...方法重新获得布局
     * 同时, 当屏幕旋转的时候collectionView的bounds也会调用这个方法
     如果设置为false, 那么将不会达到屏幕适配的效果,
     * 需要注意的是, 当collectionView执行一些操作(delete insert reload)等的时候,
     不会调用这个方法, 会直接重新调用上面的prepareLayout()...方法重新获得布局
    */
//    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
//        return true
//    }
}



一个左对齐

//
//  UICollectionViewLeftAlignedLayout.swift
//  test
//
//  Created by boosj on 2017/8/14.
//  Copyright © 2017年 boosjcz. All rights reserved.
//

import UIKit

extension UICollectionViewLayoutAttributes {
    
    /** 每行第一个item左对齐 **/
    func leftAlignFrame(_ sectionInset:UIEdgeInsets) {
        var frame = self.frame
        frame.origin.x = sectionInset.left
        self.frame = frame
    }
}

class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout {
    
    //MARK: - 重新UICollectionViewFlowLayout的方法
    
    
    override init() {
        super.init()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    /** Collection所有的UICollectionViewLayoutAttributes */
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributesToReturn = super.layoutAttributesForElements(in: rect)!
        var attributesCopy = [UICollectionViewLayoutAttributes]()
        for attributes in attributesToReturn {
            if nil == attributes.representedElementKind {
                let itemAttributesCopy = attributes.copy() as! UICollectionViewLayoutAttributes
                let indexPath = itemAttributesCopy.indexPath
                
                itemAttributesCopy.frame = self.layoutAttributesForItem(at: indexPath)!.frame
               
                // manipulate itemAttributesCopy
                attributesCopy.append(itemAttributesCopy)

            }else{
                // 忘记把这里app下 所以才没有进 头部代理
               attributesCopy.append(attributes)
            }
        }
        return attributesCopy // (copy 版 数据 防止警告 ,但是会无发进入头部代理)
    }
//
    /** 每个item的UICollectionViewLayoutAttributes */
    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        //现在item的UICollectionViewLayoutAttributes
        let currentItemAttributes = super.layoutAttributesForItem(at: indexPath)?.copy() as! UICollectionViewLayoutAttributes
        //现在section的sectionInset
        let sectionInset = self.evaluatedSectionInset(indexPath.section)
        //是否是section的第一个item
        let isFirstItemInSection = indexPath.item == 0
        //出去section偏移量的宽度
        let layoutWidth: CGFloat = self.collectionView!.frame.width - sectionInset.left - sectionInset.right
        //是section的第一个item
        if isFirstItemInSection {
            //每行第一个item左对齐
            currentItemAttributes.leftAlignFrame(sectionInset)
            return currentItemAttributes
        }
        
        //前一个item的NSIndexPath
        let previousIndexPath = IndexPath(item: indexPath.item - 1, section: indexPath.section)
        //前一个item的frame
        let previousFrame = self.layoutAttributesForItem(at: previousIndexPath)!.frame
        //为现在item计算新的left
        let previousFrameRightPoint: CGFloat = previousFrame.origin.x + previousFrame.size.width
        //现在item的frame
        let currentFrame = currentItemAttributes.frame
        //现在item所在一行的frame
        let strecthedCurrentFrame = CGRect(x: sectionInset.left, y: currentFrame.origin.y, width: layoutWidth, height: currentFrame.size.height)
        
        //previousFrame和strecthedCurrentFrame是否有交集,没有,说明这个item和前一个item在同一行,item是这行的第一个item
        let isFirstItemInRow = !previousFrame.intersects(strecthedCurrentFrame)
        //item是这行的第一个item
        if isFirstItemInRow {
            //每行第一个item左对齐
            currentItemAttributes.leftAlignFrame(sectionInset)
            return currentItemAttributes
        }
        //不是每行的第一个item
        var frame = currentItemAttributes.frame
        //为item计算新的left = previousFrameRightPoint + item之间的间距
        frame.origin.x = previousFrameRightPoint + self.evaluatedMinimumInteritemSpacing(indexPath.item)
        //为item的frame赋新值
        currentItemAttributes.frame = frame
        return currentItemAttributes
    }

    //MARK: - System
    
    /** item行间距 **/
    fileprivate func evaluatedMinimumInteritemSpacing(_ ItemAtIndex:Int) -> CGFloat     {
        if let delete = self.collectionView?.delegate {
            weak var delegate = (delete as! UICollectionViewDelegateFlowLayout)
            if delegate!.responds(to: #selector(UICollectionViewDelegateFlowLayout.collectionView(_:layout:minimumInteritemSpacingForSectionAt:))) {
                let mini =  delegate?.collectionView!(self.collectionView!, layout: self, minimumInteritemSpacingForSectionAt: ItemAtIndex)
                if mini != nil {
                    return mini!
                }
            }
        }
        return self.minimumInteritemSpacing
    }
    
    /** section的偏移量 **/
    fileprivate func evaluatedSectionInset(_ itemAtIndex:Int) -> UIEdgeInsets {
        if let delete = self.collectionView?.delegate {
            weak var delegate = (delete as! UICollectionViewDelegateFlowLayout)
            if delegate!.responds(to: #selector(UICollectionViewDelegateFlowLayout.collectionView(_:layout:insetForSectionAt:))) {
                let sectionInset =  delegate?.collectionView!(self.collectionView!, layout: self, insetForSectionAt: itemAtIndex)
                if sectionInset != nil {
                    return sectionInset!
                }
            }
        }
        return self.sectionInset
    }
}



标签: 暂无
最后更新:2022年 11月 11日

陈昭

IT 程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

COPYRIGHT © 2022 chenzhao. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang