swift首页轮播 轻量级 超级缓存

jopen 5年前
   <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>