//
// 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
}
}
文章评论