自定义下拉刷新

 


  自定义下拉刷新



// 代表当前控件的状态

enum SHRefreshControlState: Int {

    // 正常

    case Normal = 0

    // 下拉中

    case Pulling = 1

    // 刷新中

    case Refreshing = 2

}

// 控件的高度

let RefreshControlH: CGFloat = 50

class SHRefreshControl: UIControl {

    

    var scrollView: UIScrollView?

    // 记录当前状态

    var shState:SHRefreshControlState = .Normal{

        didSet{

            

            switch shState {

            case .Normal:

                messageLabel.text = "正常"

                UIView.animateWithDuration(0.25, animations: { () -> Void in

                    self.pullImageView.transform = CGAffineTransformIdentity

                })

                

                // 判断上一个状态为刷新中

                if oldValue == .Refreshing {

                    UIView.animateWithDuration(0.25, animations: { () -> Void in

                        self.scrollView?.contentInset.top -= RefreshControlH

                        }, completion: { (_) -> Void in

                            // 显示箭头

                            self.pullImageView.hidden = false

                            // 停止动画

                            self.indicatorView.stopAnimating()

                    })

                }

                

            case .Pulling:

                print("下拉中")

                messageLabel.text = "下拉中"

                

                UIView.animateWithDuration(0.25, animations: { () -> Void in

                    self.pullImageView.transform = CGAffineTransformMakeRotation(CGFloat(-3*M_PI))

                    

                })

                

            case .Refreshing:

                messageLabel.text = "刷新中"

                // 设置动画 增加scrollView 滑动距离

                // 隐藏箭头

                pullImageView.hidden = true

                // 菊花开始动画

                indicatorView.startAnimating()

                UIView.animateWithDuration(0.25, animations: { () -> Void in

                    self.scrollView?.contentInset.top += RefreshControlH

                    }, completion: { (_) -> Void in

                        // 告知外界可以刷新了

                        self.sendActionsForControlEvents(UIControlEvents.ValueChanged)

                        

                })

            }

        }

    }


    override init(frame: CGRect) {

        

        super.init(frame: CGRect(x: 0, y: -RefreshControlH, width: UIScreen.mainScreen().bounds.width, height: RefreshControlH))

        setupUI()

    }


    required init?(coder aDecoder: NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }

    

    // MARK: - 供外界调用的方法

    func endRefreshing(){

        // 01 当前的状态改成正常

        // 02 减去50

        shState = .Normal

    }

    

    // 该控件将要加载到那个父视图

    override func willMoveToSuperview(newSuperview: UIView?) {

        // 判断他是否为nil 而且是可以滚动的

        guard let scrollView = newSuperview as? UIScrollView else{

            return

        }

        // kvo 

        self.scrollView = scrollView

        // 监听scrollView 使用kvo

        self.scrollView?.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New, context: nil)

        

    }

    

    // 得到scrollView 的变化

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {

        

        getSHRefreshControlState(self.scrollView!.contentOffset.y)

    }

    /*

    

    - 当用户拖动tableView 而且没有松手

        - contentOffset.y > -114 显示正常 且当前状态为下拉中

        - contentOffset.y <= -114 下拉中 且当前的状态为正常

    - 当用户拖动tableView 而且松手了

        -  如果当前的状态为 下拉中   ---》刷新中

        - 如果用户松手了 而且当前的状态为下拉中 才能进入刷新中

    */

    // 判断当前刷新控件显示状态

    func getSHRefreshControlState(contentOffsetY: CGFloat){

        

        // -64

        let contentInsetTop = self.scrollView?.contentInset.top ?? 0

        

        // 代表用户正在拖动

        if self.scrollView!.dragging {

            if contentOffsetY > -contentInsetTop - RefreshControlH && shState == .Pulling{

                shState = .Normal

            }else if contentOffsetY <= -contentInsetTop - RefreshControlH && shState == .Normal{

                shState = .Pulling

            }

            

        }else {

            // 代表用户松手了

            if shState == .Pulling {

                shState = .Refreshing

            }

            

        }

    }

    

    // MARK: - 设置视图

    private func setupUI(){

        backgroundColor = UIColor.orangeColor()

        // 添加控件

        addSubview(messageLabel)

        addSubview(pullImageView)

        addSubview(indicatorView)

        

        messageLabel.translatesAutoresizingMaskIntoConstraints = false

        

        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))

        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))

        

        pullImageView.translatesAutoresizingMaskIntoConstraints = false

        

        addConstraint(NSLayoutConstraint(item: pullImageView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: -35))

        addConstraint(NSLayoutConstraint(item: pullImageView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))

        

        indicatorView.translatesAutoresizingMaskIntoConstraints = false

        

        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: -35))

        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))

        

    }

    

    // MARK: - 懒加载控件

    private lazy var messageLabel: UILabel = {

        let lab = UILabel()

        lab.text = "正常"

        lab.textColor = UIColor.whiteColor()

        lab.font = UIFont.systemFontOfSize(14)

        return lab

    }()

    // 箭头

    private lazy var pullImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))

    // 菊花

    private lazy var indicatorView: UIActivityIndicatorView = {

        let view = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.White)

        return view

    }()

    

    deinit{

        // 记得移除

        self.scrollView?.removeObserver(self, forKeyPath: "contentOffset")

    }

    



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
scroll-view组件可以用于实现自定义下拉刷新效果。通过设置scroll-view的属性,可以实现自定义下拉刷新动画和触发事件。在wxml部分,可以设置scroll-view的refresher-enabled属性为true,表示开启下拉刷新功能。同时,可以设置refresher-threshold属性来定义下拉刷新的触发阈值,当下拉距离超过该阈值时,触发下拉刷新事件。还可以设置refresher-triggered属性来控制下拉刷新的状态,当该属性为true时,表示正在进行下拉刷新。在触发下拉刷新事件时,可以通过bindrefresherrefresh属性绑定一个事件处理函数,用于处理下拉刷新的逻辑。通过在该事件处理函数中,可以自定义下拉刷新的动画效果和数据更新操作。\[2\]\[3\] #### 引用[.reference_title] - *1* [scroll-view实现自定义下拉刷新](https://blog.csdn.net/qq_40666120/article/details/108284680)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [微信小程序scroll-view实现自定义刷新](https://blog.csdn.net/weixin_42883683/article/details/123920355)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值