下拉刷新实现思路

模仿微博的刷新,这个刷新的控件是添加到tabelView上的,有时候系统给的刷新控件已经不满足我们的需要了,所以要自定义了

**首先用枚举确定类型,是正常,下拉,还是刷新

/// 枚举确定类型
enum RefreshType:Int {
    case Normal = 0
    case Pulling = 1
    case Refresh = 2
}

**将要移动到控件到父view 上, 使用kvo监听,得到scroll的变化,关键是通过scrollView.contentOffSet.y,通过判断它的改变,判断是哪种状态.

 //MARK: - 01.将控件添加到视图
    override func willMoveToSuperview(newSuperview: UIView?) {
        //判断是否为nil,并且能够滚动
        guard let scrollView = newSuperview as?UIScrollView else{
            return
        }
        //kvo监听属性的变化
        self.scrollView = scrollView
        self.scrollView?.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New, context: nil)
        
    }
    
    //MARK: - 得到scroll 的变化
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer) {
        
        getRefreshStates(self.scrollView!.contentOffset.y)
        
    }

    //MARK: - 通过contentOffsetY 判断状态
    /*
    拖动时候,未松手
    - 小于     控件高 + 导航栏高 -->正常状态
    - 大于/等于 控件高 + 导航栏高 -->下拉状态
    拖动,松手
    - 下拉状态,改变刷新状态
    */

    func getRefreshStates(contentOffsetY:CGFloat){

    let contentInsetTop = self.scrollView?.contentInset.top ?? 0
    if contentInsetTop == 0
        {
            //自己隐藏
            self.hidden = true
            
        }else{
            self.hidden = false
        if self.scrollView!.dragging {//未松手
            if contentOffsetY > -contentInsetTop - refreshHeight && wwState == .Pulling{
                wwState = .Normal
            }else if contentOffsetY <= -contentInsetTop - refreshHeight && wwState == .Normal{
                wwState = .Pulling
            }
            
        }else {//松手
            if wwState == .Pulling{
                wwState = .Refresh
            }
            
        }
    }
}

这里是当它是正常状态下需要判断上一状态,从而做出不同的需求

/// 控件高度
let refreshHeight:CGFloat = 50
class WWRefreshView: UIControl {

    //属性 scrollview
    var scrollView : UIScrollView?
    var wwState:RefreshType = .Normal{
        didSet{
            
            switch wwState{
            case .Normal:
            messageLabel.text = "正常"
            UIView.animateWithDuration(0.25) { () -> Void in
                self.pullImage.transform = CGAffineTransformIdentity
            }
            
            //判断上一个状态是刷新
            if oldValue == .Refresh{
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.scrollView?.contentInset.top -= refreshHeight
                    },completion:{ (_) -> Void in
                        // 显示箭头
                        self.pullImage.hidden = false
                        // 停止动画
                        self.indicatorView.stopAnimating()
                })
            }
            case .Pulling://下拉
                messageLabel.text = "下拉"
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.pullImage.transform = CGAffineTransformMakeRotation(CGFloat(-3*M_PI))
            })
            case .Refresh:
                messageLabel.text = "刷新"
                //隐藏箭头,开始转圈
                pullImage.hidden = true
                indicatorView.startAnimating()
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.scrollView?.contentInset.top += refreshHeight
                    }, completion: { (_) -> Void in
                        
                        //外界可以调用
                        self.sendActionsForControlEvents(UIControlEvents.ValueChanged)
                })
        }
    }
}

** 最后要移除

 //移除
    deinit{
        self.scrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }

}

你可能感兴趣的:(下拉刷新实现思路)