import UIKit
class WorkViewF2lowLayout: UICollectionViewFlowLayout {
var numRow:Int = 0;//行数
var numCol:Int = 0;//列数
var pageNumber :NSInteger = 1;
var itemSpacing : CGFloat = 0;//左右间距
var lineSpacing :CGFloat = 0;// 上下间距
var contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
//所有cell的布局属性
var layoutAttributes: [UICollectionViewLayoutAttributes] = [UICollectionViewLayoutAttributes]();
override init() {
super.init();
self.itemSize = CGSize(width: SCREEN_WIDTH/4 , height: 95);
self.scrollDirection = .horizontal
self.numRow = 2;
self.numCol = 4;
self.contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
override func prepare() {
let itemNumber : NSInteger = ((self.collectionView?.numberOfItems(inSection: 0))!)
pageNumber = (itemNumber-1)/(numRow * numCol)+1 //13-1 12/8 = 1 :2
}
//返回制定indexPath的item布局信息
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributte = UICollectionViewLayoutAttributes.init(forCellWith: indexPath)
var fram1 : CGRect = CGRect.init(x: 0, y: 0, width: 0, height: 0)
fram1.size = self.itemSize
let number : Int = numCol*numRow
var m : Int = 0
var p : Int = 0
if indexPath.item >= number {
p = indexPath.item/number //大于等于8 的时候 p = 1
m = (indexPath.item%number) / numCol // m来确定第二页的时候的m
}else {
m = indexPath.item/numCol //每页8个item.当小于8(0...7)m/4 来判断是第一行还是第二行, m用来计算item的y
}
let n = indexPath.item%numCol //n用来计算item的x
let k = indexPath.section + p //计算有几页 这个flowlayout只有一个分区的时候计算正确
print("item ===\(indexPath.item),n====\(n),m===\(m),p==\(p),k===\(k)")
let width :CGFloat = self.itemSize.width
let height :CGFloat = self.itemSize.height
//计算水平距离 item的宽度*第几个item+第几个item *左右间距+左间距+第几页*k集合视图的宽度
var x:CGFloat = CGFloat(n) * width + CGFloat(n) * itemSpacing + self.contentInsets.left
x = x + CGFloat(k) * (self.collectionView?.frame.size.width)!
//计算y 第几行*item的高度 + 第几行*上下间距+ top间距
let y :CGFloat = CGFloat(m) * height + CGFloat(m) * lineSpacing + self.contentInsets.top
//设置item 的frame
attributte.frame = CGRect.init(x:x, y: y, width: self.itemSize.width, height: self.itemSize.height)
print("frame======\(attributte.frame)")
return attributte
}
//为所有item返回一个layout attributes数组,数组中元素的类型为UICollectionViewLayoutAttributes。UICollectionViewLayoutAttributes记录了一个layout的位置、大小、透明度等信息。
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let temAttributes = NSMutableArray.init(capacity: 1)
let N :Int = ((self.collectionView?.numberOfSections)!)
for j in 0..<N{
let count : Int = (self.collectionView?.numberOfItems(inSection: j))!
for i in 0..<count{
let indexPath : NSIndexPath = NSIndexPath.init(item: i, section: j)
//循环添加UICollectionViewLayoutAttributes进数组
temAttributes.add(self.layoutAttributesForItem(at: indexPath as IndexPath) as Any)
}
}
return (temAttributes as! [UICollectionViewLayoutAttributes])
}
//重写集合视图的size
override open var collectionViewContentSize: CGSize {
return CGSize.init(width: (self.collectionView?.bounds.size.width)! * CGFloat(pageNumber), height: (self.collectionView?.bounds.size.height)!)
}
//询问是否需要从新布局
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
使用方法
import UIKit
import Foundation
class workView: UIView ,UICollectionViewDelegate,UICollectionViewDataSource,UIScrollViewDelegate {
var collectionView:UICollectionView?
var pagCon :UIPageControl?
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.yellow
collectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: frame.width, height: frame.height), collectionViewLayout: WorkViewF2lowLayout())
collectionView?.backgroundColor = UIColor.white
collectionView?.delegate = self
collectionView?.dataSource = self
collectionView?.isPagingEnabled = true
collectionView?.register(UINib.init(nibName: "workCollCell", bundle: Bundle.main), forCellWithReuseIdentifier: "cell")
self.addSubview(collectionView!)
pagCon = UIPageControl.init(frame: CGRect(x: 0, y: 147.5, width: 90, height: 10))
pagCon?.numberOfPages = 2
pagCon?.currentPageIndicatorTintColor = UIColor.green
pagCon?.center = CGPoint.init(x: SCREEN_WIDTH/2, y: 180)
pagCon?.pageIndicatorTintColor = UIColor.blue
self.addSubview(pagCon!)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageNumber:Int = Int(scrollView.contentOffset.x / SCREEN_WIDTH + 0.5);
pagCon?.currentPage = pageNumber
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 13
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! workCollCell
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("第---\(indexPath.section)区---\(indexPath.row)行")
}
}
注意的点: 1.当计算item的frame的x是,习惯性的写了一长串的计算式子,然后就报错了,错误信息的大概意思是不能在时间内计算好结果。解决方式就是需要我们去拆分,分开计算。。。
2. swift计算中 Int和CGFloat不能进行加减乘除等数学计算,只能先把int数据转成CGFloat,类如 CGFloat(m)
3. oc中的for (int i = 0, i<5;i++)已经被取消了,swift中使用 for i in 0..<5 ;0..<5代表的是0到4,0...5代表的0到5
4.swift中的print 很方便,不用在像以前oc还需要写它的类型,现在只要\() 例如:print("ssss的值==\(m)")