swift首页轮播 轻量级 超级缓存
jopen
9年前
<h2>用swift写的首页轮播控件</h2> <p>如果你觉得对你有帮助,请给个Star,写了几天也不容易, 您的支持是我前进的动力! <a href="/misc/goto?guid=4959653431644288245" target="_blank">github代码地址</a></p> <h3>网上找了一些首页轮播,写的或多或少有一些问题,用着不舒服,自己用swift写了一个轮播控件,有如下特点:</h3> <blockquote> <ul> <li>使用自己写的网络请求SSNetWorking,无需第三方库</li> <li>由于轮播图一般较少,采用的plist存储用SSImageFileManager去管理存储</li> <li>网络请求下载图片会在需要时请求下载,已下载完的图片会缓存起来,再次启动也不会再次请求,不会无故浪费用户流量</li> <li>轮播图上需要点击链接,只需要调用一个block便可加上点击</li> </ul> </blockquote> <h3>使用方法</h3> <blockquote> <ul> <li> <p>把SSCycleScroll文件夹拖入到工程中:</p> <div class="image-package" href="https://simg.open-open.com/show/e2731b58e7fea5832b0b0a18f7cf01b8.png"> <img src="https://simg.open-open.com/show/e2731b58e7fea5832b0b0a18f7cf01b8.png" width="234" height="179" data-original-src="https://simg.open-open.com/show/5cca1ce9979e4f97521a0358cfd59e72.png" /> <br /> <div class="image-caption"> QQ20151124-0.png </div> </div> </li> <li> <p>defaultBackground.jpg换成自己的背景,当没有网络时,会用本地的这一张图轮播,imageDownload.plist请也要带着,初始化时会用到,如果不用网络图片,只用SSCycleScrollView.swift这一个文件就可以了;</p> </li> <li> <p>初始化一个SSCycleScrollView:</p> <pre class="brush:cpp; toolbar: true; auto-links: false;">self.mainScrollView = SSCycleScrollView.init(frame: currentRect, animationDuration: 3, inputImageArray: self.scrollImageArray) self.view.addSubview(self.mainScrollView!)</pre></li> <li>只需要要传入一个image array就可以了,有网络下载的,等下载完,更新SSCycleScrollView中的allImageArray就可以了;</li> <li>可以这样请求:<pre class="brush:cpp; toolbar: true; auto-links: false;"> SSDownloadManager.sharedInstance.request(kMainScrollURL) { (finished, error) -> Void in if finished { /********** 所有图片都下载完成后,reloadCycleScroll中的array **********/ self.reloadScrollImageArray() print("download image finished") } } self.addMainScrollView()</pre>下载完图片后,reloadScrollImageArray:<pre class="brush:cpp; toolbar: true; auto-links: false;"> func reloadScrollImageArray() { let imageModel = SSImageDownloadModel.sharedInstance let imageCount = imageModel.imageList.count self.scrollImageArray.removeAll() if imageCount > 0 { for item in imageModel.imageList { if let imageUrl = item.imageCachePath { if imageUrl.characters.count > 0 { if let image = UIImage(contentsOfFile: imageUrl) { self.scrollImageArray.append(image) } } } } } if self.scrollImageArray.count > 0 { self.mainScrollView?.allImageArray = self.scrollImageArray } }</pre> <h3>注意点</h3> 使用前根据自己服务器中json格式,配置好本地的imageDown.plist, 和SSImageDownModel的SSImageDownloadItem,不要忘记info.plist中的App Transport Security Settings,以允许http连接。</li> </ul> </blockquote> <h3>原理详解</h3> <p>如果愿意看,下面还能写一点东西。就算你觉得这种下载方式或者是轮播控件不好用,对于对plist存储不熟悉的人来说,这一篇也能学到plist的存储,后期还会用更好的方式去存储。</p> <blockquote> <ul> <li>请求json时,会把服务器上最新的json文件拿下来,写到本地plist中去;</li> <li>对plist存储读写时,是用md5值做这条数据的唯一标识;</li> <li>对于每条数据,缓存的路径为/tmp/imageCache/md5.jpg, 如果在缓存中没有发现这个图片,才会去网络请求图片;</li> <li>SSNetworking中,请求方法用的URLSession, 请求 json 时用的ephemeralSessionConfiguration 配置请求,每次请求,没用缓存,如果用default,服务器中 son 修改后,可能请求不回来最新的。</li> </ul> </blockquote> <h4>SSCycScrollView</h4> <blockquote> <p>初始化后会启动一个定时器,repeat调用一个timerFired方法,方法中每次对scrollview加一个自己宽度的offset:</p> <pre class="brush:cpp; toolbar: true; auto-links: false;">func timerFired() { let xOffset = Int(self.contentOffset.x/kScreenWidth) let xOffsetFloat = CGFloat(xOffset) * kScreenWidth let newOffset = CGPointMake(xOffsetFloat + CGRectGetWidth(self.frame), self.contentOffset.y) self.setContentOffset(newOffset, animated: true) }</pre> <p>没有直接加xOffset, 而是对其做了一个换算,确保每次加的offset是自己宽度的整数倍。<br /> 在scrollViewDidScroll方法,每次计算前一个,当前,后一个index,确保index范围为index >= 0 && index < allImageArray.count, 每次滚动后都会三个imageView中的image做重新赋值:</p> <pre class="brush:cpp; toolbar: true; auto-links: false;"> self.previousDisplayView?.image = self.allImageArray[previousArrayIndex] self.currentDisplayView?.image = self.allImageArray[self.currentArrayIndex] self.lastDisplayView?.image = self.allImageArray[lastArrayIndex] self.contentOffset = CGPointMake(CGRectGetWidth(self.frame), 0)</pre> <p>上面最后一行设置contenOffset非常重要,每次把scrollView的位置重置为1个自身宽度的offset。</p> </blockquote> <h3>小结</h3> <blockquote> <p>如果你觉得有不好的地方,可以提出来,大家一块研究一下,欢迎常来我的<a href="/misc/goto?guid=4959653431749466921" target="_blank">仓库</a>,别忘记给个star!</p> <p><a href="/misc/goto?guid=4959653431644288245" target="_blank">github代码地址</a></p> </blockquote> <p>来自: <a href="/misc/goto?guid=4959653431839540507" rel="nofollow" target="_blank">http://www.jianshu.com/p/d7bf5fe4d9fa</a></p>