Swift 让我来告诉你封装下拉刷新多么简单

linger 8年前
   <p style="text-align:center"><img alt="Swift 让我来告诉你封装下拉刷新多么简单" src="https://simg.open-open.com/show/41b03f3dfc9d768c37995884c3a83ff4.jpg"></p>    <p>下拉刷新可以说是每个项目的必须品,最近在做一个 <code>Swift</code> 的项目,本着以锻炼自己的目的,封装了一个下拉刷新库 <code>LCRefresh</code> ,在这里分享给大家。</p>    <h2>1、如何使用 LCRefresh</h2>    <p>使用 <code>LCRefresh</code> 非常方便,只需添加一行代码。</p>    <p>添加下拉刷新 和 上拉加载</p>    <pre>  <code class="language-swift">table.addRefreshHeaderWithBlock {          print("Header 刷新")          //TODO   }    table.addRefreshFooterWithBlock {          print("Footer 刷新")          //TODO  }</code></pre>    <p>完成刷新</p>    <pre>  <code class="language-swift">weak var weakSelf = self  if weakSelf!.table.isHeaderRefreshing() {      weakSelf!.table.endHeaderRefreshing()  }    if weakSelf!.table.isFooterRefreshing() {      weakSelf!.table.endFooterRefreshing()  }</code></pre>    <p>数据加载完毕</p>    <pre>  <code class="language-swift">weakSelf!.table.setDataLoadover()    weakSelf!.table.resetDataLoad()</code></pre>    <p>刷新的效果图</p>    <p><img alt="Swift 让我来告诉你封装下拉刷新多么简单" src="https://simg.open-open.com/show/b8ae8f90c7a41eaaa256188c72f0cdee.png"></p>    <p>HeaderRefresh.png</p>    <p><img alt="Swift 让我来告诉你封装下拉刷新多么简单" src="https://simg.open-open.com/show/1cd0efccae651813595e2aac5a008f81.png"></p>    <p>FooterRefresh.png</p>    <h2>2、如何去封装自己的刷新控件</h2>    <blockquote>     <p>这里分享一下封装刷新控件的心路历程</p>    </blockquote>    <h3>① 创建刷新视图,并创建View的各种状态</h3>    <p><img alt="Swift 让我来告诉你封装下拉刷新多么简单" src="https://simg.open-open.com/show/81f0e1cff347febb329a0a63f8935ca6.jpg"></p>    <p>LCRefreshHeader</p>    <pre>  <code class="language-swift">extension LCRefreshHeader{    /** 各种状态切换 */    private func setNomalStatus() {        if activity.isAnimating() {            activity.stopAnimating()        }        activity.hidden = true          contenLab.text = "下拉可以刷新"        image.hidden = false          UIView.animateWithDuration(0.2) {             self.image.transform = CGAffineTransformIdentity        }    }      private func setWaitRefreshStatus() {        if activity.isAnimating() {            activity.stopAnimating()        }        activity.hidden = true          contenLab.text = "松开立即刷新"        image.hidden = false          UIView.animateWithDuration(0.2) {             self.image.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI))          }    }      private func setRefreshingStatus() {        activity.hidden = false        activity.startAnimating()          contenLab.text = "正在刷新数据..."        image.hidden = true    }  }</code></pre>    <h3>②拓展 <code>UIScrollView</code> 把刷新View添加在 <code>ScrollView</code> 上</h3>    <pre>  <code class="language-swift">/** 添加下拉刷新 */  func addRefreshHeaderWithBlock(refreshBlock:()->Void){      /** 添加header */      weak var weakSelf = self        header = LCRefreshHeader.instanceFromNibBundle() as? LCRefreshHeader      guard header != nil else{          print("Header加载失败")          return      }      header!.center = LCRefreshHeaderCenter        let headerView = UIView.init(frame: CGRectMake(LCRefreshHeaderX, LCRefreshHeaderY, LCRefreshScreenWidth, LCRefreshHeaderHeight))      headerView.backgroundColor = UIColor.clearColor()      headerView.addSubview(header!)      weakSelf!.addSubview(headerView)        /** 设置代理信息 */      weakSelf!.delegate = weakSelf      weakSelf!.panGestureRecognizer.addTarget(weakSelf!, action: #selector(UIScrollView.scrollViewDragging(_:)))        lcHeaderBlock = refreshBlock  }</code></pre>    <blockquote>     <p>添加视图,设置 delegate 来监测 <code>ScrollView</code> 滑动,由于是在 extension 中,delegate 中的 <code>scrollViewDidEndDragging</code> 方法无响应,最后采取了监测 <code>ScrollView</code> 的 <code>pan</code> 手势识别,来处理拖拽响应。<br> 如果你有好的建议,欢迎与我讨论</p>    </blockquote>    <h3>③根据<code>ScrollView</code>的 <code>contentOffset</code> 来区分是下拉刷新还是上拉加载,然后根据 <code>contentOffset</code> 的值来切换刷新View的状态</h3>    <pre>  <code class="language-swift">/** 滑动相关 */  public func scrollViewDidScroll(scrollView: UIScrollView) {      let offSet = scrollView.contentOffset.y      let scrollHeight = scrollView.bounds.size.height      let inset = scrollView.contentInset      var currentOffset = offSet + scrollHeight - inset.bottom      let maximumOffset = scrollView.contentSize.height        /** 数据未充满屏幕的情况 **/      if maximumOffset < scrollHeight {          currentOffset = offSet + maximumOffset - inset.bottom      }        if offSet < 0 {          /** 下拉刷新 */          scrollHeader(offSet)          refreshObj = LCRefreshObject.Header      }else if currentOffset - maximumOffset > 0 {          /** 上拉刷新 */            guard footer!.refreshStatus != LCRefreshFooterStatus.Loadover else {              return          }            scrollFooter(currentOffset - maximumOffset)          refreshObj = LCRefreshObject.Footer        }else{          /** 无刷新对象 */          refreshObj = LCRefreshObject.None      }  }</code></pre>    <p>View状态切换</p>    <pre>  <code class="language-swift">private func scrollHeader(offSet: CGFloat) {//参数为负数      guard header != nil else{          print("Header加载失败")          return      }      guard header!.refreshStatus != LCRefreshHeaderStatus.Refreshing else{          return      }      if offSet < -LCRefreshHeaderHeight {          header!.setStatus(LCRefreshHeaderStatus.WaitRefresh)      }else{          header!.setStatus(LCRefreshHeaderStatus.Normal)      }  }</code></pre>    <h3>④最后拖拽结束时再根据刷新对象切换View 到刷新状态。</h3>    <pre>  <code class="language-swift">/** 拖拽相关 */  func scrollViewDragging(pan: UIPanGestureRecognizer){      if pan.state == .Ended{          if refreshObj == LCRefreshObject.Header {              draggHeader()            }else if refreshObj == LCRefreshObject.Footer{              draggFooter()          }      }  }</code></pre>    <blockquote>     <p>这之间涉及到<code>contentOffset</code>值的设置,在这里就不一一明说了,给出的源码里都有。</p>    </blockquote>    <p>现在只是开发出了这一种样式,以后会更多的样式以供大家使用,当然,你也可以根据给出的源码自己来修改样式。</p>    <p><br> 来自:http://www.jianshu.com/p/725cd8028c8a<br>  </p>