iOScollectionView广告无限滚动实例(Swift实现)
程序员文章站
2023-12-19 23:37:04
今天公司里的实习生跑过来问我一般app上广告的无限滚动是怎么实现的,刚好很久没写博客了,就决定写下了,尽量帮助那些处于刚学ios的程序猿.
做一个小demo,大概实现效果...
今天公司里的实习生跑过来问我一般app上广告的无限滚动是怎么实现的,刚好很久没写博客了,就决定写下了,尽量帮助那些处于刚学ios的程序猿.
做一个小demo,大概实现效果如下图所示:
基本实现思路:
1. 在你需要放置无限滚动展示数据的地方把他的数据,在原本的基础上把你要展示的数据扩大三倍.(当然扩大两倍也是可以的,三倍的话,比较好演示)
// mark: - 设置数据源 func collectionview(_ collectionview: uicollectionview, numberofitemsinsection section: int) -> int { // print(self.arraym.count) return self.arraym.count * 3 }
2.当在定时器的作用下,或者在拖动情况存下滚动到第八个时候,设置此时的collectionview.contentoffset.x等于滚动到第三个cell的contentoffset.x
if collectionview.contentoffset.x == cgfloat(3 * self.arraym.count - 1) * self.collectionview.bounds.width { self.collectionview.contentoffset.x = cgfloat(self.arraym.count - 1) * self.collectionview.bounds.width }
3.当拖动到第0个cell时,设置此时的collectionview.contentoffset.x等于第六个cell的contentoffset.x
if collectionview.contentoffset.x == 0 { self.collectionview.contentoffset.x = cgfloat(2 * self.arraym.count - 1) * self.collectionview.bounds.width }
代码如下:
我在代码中用到5张照片,所以应该一共有15个cell
import uikit class viewcontroller: uiviewcontroller ,uicollectionviewdatasource, uicollectionviewdelegate { @iboutlet weak var collectionview: uicollectionview! var timer : timer? var arraym : [bomodel] = [] { didset { self.collectionview.reloaddata() } } static let cellid = "cell" override func viewdidload() { super.viewdidload() self.collectionview.datasource = self self.collectionview.delegate = self // 加载数据 loaddata() self.collectionview.register(uinib.init(nibname: "bocollectionviewcell", bundle: nil), forcellwithreuseidentifier: viewcontroller.cellid) //设置collextionview setupcollectionview() // 开启定时器 startimer() } /// 从polist中加载数据 func loaddata() { let stemp: nsarray = nsarray(contentsoffile: bundle.main.path(forresource: "shops.plist", oftype: nil)!)! for dict in stemp { let model = bomodel.init(dict: dict as! [string : any]) self.arraym.append(model) } } /// 设置cellection的布局方式 /// /// - returns: 一个布局类型 func setupcollectionflowlayout() -> (uicollectionviewflowlayout) { let flowlayout = uicollectionviewflowlayout() flowlayout.itemsize = self.collectionview.bounds.size flowlayout.minimumlinespacing = 0 flowlayout.minimuminteritemspacing = 0 flowlayout.scrolldirection = .horizontal flowlayout.sectioninset = uiedgeinsetsmake(0, 0, 0, 0) return flowlayout } /// 设置collectionview func setupcollectionview() -> () { self.collectionview.collectionviewlayout = self.setupcollectionflowlayout() self.collectionview.showsverticalscrollindicator = false self.collectionview.showshorizontalscrollindicator = false self.collectionview.ispagingenabled = true } // mark: - 设置数据源 func collectionview(_ collectionview: uicollectionview, numberofitemsinsection section: int) -> int { // print(self.arraym.count) return self.arraym.count * 3 } func collectionview(_ collectionview: uicollectionview, cellforitemat indexpath: indexpath) -> uicollectionviewcell { let cell = self.collectionview.dequeuereusablecell(withreuseidentifier: viewcontroller.cellid, for: indexpath) as! bocollectionviewcell cell.model = self.arraym[indexpath.row % self.arraym.count] return cell } // mark: - 实现代理方法 func scrollviewdidenddecelerating(_ scrollview: uiscrollview) { //contentoffset.x == 0 时,重新设置contentoffset.x的值 if collectionview.contentoffset.x == 0 { self.collectionview.contentoffset.x = cgfloat(2 * self.arraym.count - 1) * self.collectionview.bounds.width } //当到达最后一个cell时,重新设置contentoffset.x的值 if collectionview.contentoffset.x == cgfloat(3 * self.arraym.count - 1) * self.collectionview.bounds.width { self.collectionview.contentoffset.x = cgfloat(self.arraym.count - 1) * self.collectionview.bounds.width } } /// 开启定时器 func startimer () { let timer = timer.init(timeinterval: 1, target: self, selector: #selector(viewcontroller.nextpage), userinfo: nil, repeats: true) // 这一句代码涉及到runloop 和 主线程的知识,则在界面上不能执行其他的ui操作 runloop.main.add(timer, formode: runloopmode.commonmodes) self.timer = timer } /// 在1秒后,自动跳转到下一页 func nextpage() { // 如果到达最后一个,则变成第四个 if collectionview.contentoffset.x == cgfloat(3 * self.arraym.count - 1) * self.collectionview.bounds.width { self.collectionview.contentoffset.x = cgfloat(self.arraym.count - 1) * self.collectionview.bounds.width }else { // 每过一秒,contentoffset.x增加一个cell的宽度 self.collectionview.contentoffset.x += self.collectionview.bounds.size.width } } /// 当collectionview开始拖动的时候,取消定时器 func scrollviewwillbegindragging(_ scrollview: uiscrollview) { self.timer?.invalidate() self.timer = nil } /// 当用户停止拖动的时候,开启定时器 func scrollviewwillenddragging(_ scrollview: uiscrollview, withvelocity velocity: cgpoint, targetcontentoffset: unsafemutablepointer<cgpoint>) { startimer() } }
plist文件如下图所示:
用到的字典转模型因为比较简单的转换,就自己写了个:
import uikit class bocollectionviewcell: uicollectionviewcell { @iboutlet weak var imageview: uiimageview! var model : bomodel? { didset { guard let image = uiimage.init(named: (model?.name)!) else { return } self.imageview.image = image } } override func awakefromnib() { super.awakefromnib() } }
自定义collectionviewcell类中的内容:
import uikit class bocollectionviewcell: uicollectionviewcell { @iboutlet weak var imageview: uiimageview! var model : bomodel? { didset { guard let image = uiimage.init(named: (model?.name)!) else { return } self.imageview.image = image } } override func awakefromnib() { super.awakefromnib() } }
附: 其实这种方法比较实现无限滚动,利用了一点小技巧,用电脑测试的时候可能有一点缺陷.
原文链接:http://www.cnblogs.com/muzichenyu/p/6071757.html
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。