在写文章之前,先介绍下我的项目需求,我们项目是一个电商APP,当前功能是在商品详情里实现一个商品推荐模板,要实现商品快速浏览,并实现快速翻页功能,贴上我实现的一个效果动图,如下:
以前实现照片浏览功能,也用过collectionview实现或者pageController实现,那时候也只是单个翻页,只需要一个collectionView就可实现。当前我的需求是有多个商品需要展示,所以用到多个collectionView。
具体思路就是第一个父级collectionView充当翻页,在子页里嵌套collectionView实现商品预览,需要注意的是子页要关掉滑动交互,不然也许会出现手势冲突,剩下的就是在父级collectinView里实现翻页控制了,用到scrollView代理。好了废话少说,上代码。
```
protocolDetailRecommendTableviewCellDelegate:NSObjectProtocol{ funcselectRecommendGoodsIndex(goodsInfoId:Int)
}
classDetailRecommendTableviewCell:UITableViewCell,Reusable{
vartitleLab:UILabel!
varcollectionView:UICollectionView!
varpageContor:UIPageControl!
varseeAllBtn:UIButton!
var delegate:DetailRecommendTableviewCellDelegate!
varpresentOffset =CGPoint.zero
varisFront:Bool=true//默认往前翻页
varisDrag:Bool=false//默认没有拖动
varlastOffset =CGPoint.zero//最后一次偏移量
varblockAction:(()->())!
varpages:Int=1
varcurrentPage:Int=0
varrecommendGoodsList = [GoodsInfo](){
didSet{
if recommendGoodsList.count > 3{
self.setUP(line:2)
}else if recommendGoodsList.count > 0 && recommendGoodsList.count <= 3{
self.setUP(line:1)
}else{
self.setUP(line:0)
}
if recommendGoodsList.count > 24{
self.titleLab.isHidden=false
self.collectionView.isHidden=false
self.pageContor.isHidden=false
self.seeAllBtn.isHidden=false
}else if recommendGoodsList.count > 6 && recommendGoodsList.count <= 24{
self.titleLab.isHidden=false
self.collectionView.isHidden=false
self.pageContor.isHidden=false
self.seeAllBtn.isHidden=true
}else if recommendGoodsList.count > 3 && recommendGoodsList.count <= 6{
self.titleLab.isHidden=false
self.collectionView.isHidden=false
self.pageContor.isHidden=true
self.seeAllBtn.isHidden=true
}else if recommendGoodsList.count < 3 && recommendGoodsList.count > 0{
self.titleLab.isHidden=false
self.collectionView.isHidden=false
self.pageContor.isHidden=true
self.seeAllBtn.isHidden=true
}else{
self.titleLab.isHidden=true
self.collectionView.isHidden=true
self.pageContor.isHidden=true
self.seeAllBtn.isHidden=true
}
self.pages = recommendGoodsList.count / 6
ifrecommendGoodsList.count%6!=0{
ifself.pages<4{
self.pages+=1
}
}
self.pageContor.numberOfPages=pages
self.collectionView.reloadData()
}
}
overrideinit(style:UITableViewCell.CellStyle, reuseIdentifier:String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
//setUP()
}
requiredinit?(coder aDecoder:NSCoder) {
fatalError("init(coder:) has not been implemented")
}
funcsetUP(line:CGFloat){
ifself.collectionView!=nil{return}
titleLab=UILabel()
titleLab.font=UIFont.mg.m14
titleLab.textColor=UIColor(hexString:"#333333")
titleLab.text="為你推薦"
self.contentView.addSubview(titleLab)
titleLab.snp.makeConstraints{ (make)in
make.left.equalTo(self.contentView).offset(12)
make.top.equalTo(self.contentView.snp.top).offset(15)
}
letwid =ViewConst.screenWidth-15*2
lethei = wid /345*394/2* line
let flowLayout = UICollectionViewFlowLayout.init()
flowLayout.minimumLineSpacing=0.0
flowLayout.minimumInteritemSpacing = 0.0
flowLayout.itemSize=CGSize.init(width: wid, height: hei)
flowLayout.scrollDirection = UICollectionView.ScrollDirection.horizontal
collectionView=UICollectionView.init(frame:CGRect.zero, collectionViewLayout: flowLayout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.white
collectionView.showsHorizontalScrollIndicator = false
collectionView.register(cellType: DetailRecommendCollectionViewCell.self)
self.contentView.addSubview(collectionView)
collectionView.snp.makeConstraints{ (make)in
make.top.equalTo(titleLab.snp.bottom).offset(0)
make.left.equalTo(self.contentView.snp.left).offset(15)
make.right.equalTo(self.contentView.snp.right).offset(-15)
make.height.equalTo(hei)
}
pageContor = UIPageControl.init()
pageContor.currentPage=0
pageContor.numberOfPages = 4
pageContor.pageIndicatorTintColor = UIColor(hexString: "#d9d9d9")
pageContor.currentPageIndicatorTintColor = UIColor(hexString: "#d0323d")
self.contentView.addSubview(pageContor)
pageContor.snp.makeConstraints{ (make)in
make.top.equalTo(collectionView.snp.bottom).offset(15)
make.centerX.equalTo(collectionView)
make.size.equalTo(CGSize.init(width:30, height:10))
}
seeAllBtn=UIButton()
seeAllBtn.layer.cornerRadius = 12
seeAllBtn.layer.borderColor = UIColor.black.cgColor
seeAllBtn.layer.borderWidth = 0.5
seeAllBtn.layer.masksToBounds = true
seeAllBtn.setTitle("查看全部推荐", for: UIControl.State.normal)
seeAllBtn.setTitleColor(UIColor(hexString:"#333333"), for:UIControl.State.normal)
seeAllBtn.titleLabel?.font = UIFont.mg.r12
seeAllBtn.addTarget(self, action:#selector(btnAction), for:UIControl.Event.touchUpInside)
self.contentView.addSubview(seeAllBtn)
seeAllBtn.snp.makeConstraints{ (make)in
make.centerX.equalTo(collectionView)
make.top.equalTo(pageContor.snp.bottom).offset(10)
make.size.equalTo(CGSize.init(width:94, height:24))
}
}
@objcfuncbtnAction(){
ifletblock =blockAction{
block()
}
}
classfuncgetRecommendCellHeight(goodsList:[GoodsInfo]) ->CGFloat{
letwid =ViewConst.screenWidth-15*2
lethei = wid /345*394
ifgoodsList.count>24{
return43+ hei +69
}elseifgoodsList.count>6&& goodsList.count<=24{
return43+ hei +29
}elseifgoodsList.count>3&& goodsList.count<=6{
return43+ hei
}elseifgoodsList.count<3&& goodsList.count>0{
return43+ hei /2
}else{
return0.0
}
}
}
extension DetailRecommendTableviewCell:UICollectionViewDelegate,UICollectionViewDataSource{
funccollectionView(_collectionView:UICollectionView, numberOfItemsInSection section:Int) ->Int{
return self.pages
}
funccollectionView(_collectionView:UICollectionView, cellForItemAt indexPath:IndexPath) ->UICollectionViewCell{
letcell:DetailRecommendCollectionViewCell= collectionView.dequeueReusableCell(for: indexPath)
cell.setRecommendGoods(page: indexPath.item, goodsList:self.recommendGoodsList)
cell.selectBlockClouser= {[weakself](page,row)in
guardletstrongSelf =selfelse{return}
letgoods = strongSelf.recommendGoodsList[page *6+ row]
ifstrongSelf.delegate!=nil{
strongSelf.delegate.selectRecommendGoodsIndex(goodsInfoId: goods.goodsInfoID)
}
}
returncell
}
funcscrollViewWillBeginDragging(_scrollView:UIScrollView) {
self.presentOffset= scrollView.contentOffset
}
funcscrollViewDidEndDragging(_scrollView:UIScrollView, willDecelerate decelerate:Bool) {
letoffset = scrollView.contentOffset
ifoffset.x>self.presentOffset.x{
self.isFront=true
}else{
self.isFront=false
}
letdivisibleNum = offset.x/ (ViewConst.screenWidth-15*2)
letoffsetW =ViewConst.screenWidth-15*2
varoffsetPoint =CGPoint.zero
ifdivisibleNum <=1{
ifisFront{
self.currentPage=1
offsetPoint =CGPoint.init(x: offsetW, y:0)
}else{
self.currentPage=0
offsetPoint =CGPoint.zero
}
}elseifdivisibleNum <=2&& divisibleNum >1{
ifisFront&&self.currentPage<self.pages-1{
self.currentPage=2
offsetPoint =CGPoint.init(x: offsetW *2, y:0)
}else{
self.currentPage=1
offsetPoint =CGPoint.init(x: offsetW, y:0)
}
}elseifdivisibleNum <=3&& divisibleNum >2{
ifisFront&&self.currentPage<self.pages-1{
self.currentPage=3
offsetPoint =CGPoint.init(x: offsetW *3, y:0)
}else{
self.currentPage=2
offsetPoint =CGPoint.init(x: offsetW *2, y:0)
}
}elseifdivisibleNum >3{
ifisFront{
self.currentPage=3
offsetPoint =CGPoint.init(x: offsetW *3, y:0)
}else{
self.currentPage=2
offsetPoint =CGPoint.init(x: offsetW *2, y:0)
}
}
self.pageContor.currentPage = self.currentPage
scrollView.setContentOffset(offsetPoint, animated:true)
lastOffset= offsetPoint
isDrag=true
}
funcscrollViewWillBeginDecelerating(_scrollView:UIScrollView) {
ifisDrag{
scrollView.setContentOffset(lastOffset, animated:true)
isDrag=false
}
}
}
```
由于我们项目在实现商品详情时也是用的tableivew实现的,所以上面是在tableviewCell里面实现的第一个父级collectionView,而且UI在设计时也需要在商品数量不同时做出行高的改变。以下贴出二级collectionViewcell实现代码
```
classDetailRecommendCollectionViewCell:UICollectionViewCell,Reusable{
varcontentCollectionView:UICollectionView!
varrecommendGoodsList = [GoodsInfo]()
varcurrentPage:Int=0
//页数 row
varselectBlockClouser:((Int,Int)->())!
overrideinit(frame:CGRect) {
super.init(frame: frame)
setUP()
}
requiredinit?(coder aDecoder:NSCoder) {
fatalError("init(coder:) has not been implemented")
}
funcsetUP(){
letwid = (ViewConst.screenWidth-15*2) /3
lethei = wid /115*197
let flowLayout = UICollectionViewFlowLayout.init()
flowLayout.minimumLineSpacing=0.0
flowLayout.minimumInteritemSpacing = 0.0
flowLayout.itemSize=CGSize.init(width: wid, height: hei)
flowLayout.scrollDirection = UICollectionView.ScrollDirection.vertical
contentCollectionView=UICollectionView.init(frame:CGRect.zero, collectionViewLayout: flowLayout)
contentCollectionView.delegate = self
contentCollectionView.dataSource = self
contentCollectionView.isScrollEnabled = false
contentCollectionView.backgroundColor = UIColor.white
contentCollectionView.showsVerticalScrollIndicator = false
contentCollectionView.register(cellType: DetailRecommendGoodsCell.self)
self.contentView.addSubview(contentCollectionView)
contentCollectionView.snp.makeConstraints { (make) in
make.top.equalTo(self.contentView)
make.left.right.equalTo(self.contentView)
make.bottom.equalTo(self.contentView)
}
}
//第几个cell
//商品列表
funcsetRecommendGoods(page:Int,goodsList:[GoodsInfo]){
self.currentPage= page
self.recommendGoodsList= goodsList
self.contentCollectionView.reloadData()
}
}
extension DetailRecommendCollectionViewCell:UICollectionViewDelegate,UICollectionViewDataSource{
funccollectionView(_collectionView:UICollectionView, numberOfItemsInSection section:Int) ->Int{
letlastGoodsCount =self.recommendGoodsList.count-6*self.currentPage
iflastGoodsCount >=6{
return6
}else{
returnlastGoodsCount >0? lastGoodsCount :0
}
}
funccollectionView(_collectionView:UICollectionView, cellForItemAt indexPath:IndexPath) ->UICollectionViewCell{
letcell:DetailRecommendGoodsCell= collectionView.dequeueReusableCell(for: indexPath)
letgoods =self.recommendGoodsList[self.currentPage*6+ indexPath.item]
ifself.currentPage==0{
cell.setGoodsInfo(tag:indexPath.item,goodsInfo: goods)
}else{
//tag > 6 不显示数字标签
cell.setGoodsInfo(tag:10,goodsInfo: goods)
}
returncell
}
funccollectionView(_collectionView:UICollectionView, didSelectItemAt indexPath:IndexPath) {
ifletblock =self.selectBlockClouser{
block(self.currentPage,indexPath.item)
}
}
}
```
以上就是二级collectionview实现,剩下的商品cell就不贴出来了,简单展示就好了,涉及goodsInfoList部分可自行换成自己的数据模型。此文章纯属个人笔记,发布出去是为了相互交流,如有帮到大家,甚感荣幸,如有不足,感谢大佬指正。