//// RefreshControl.swift// //// Created by Long on 16/09/14.// copyright © 2016年 Apple. All rights reserved.//import UIKit// 自定义下拉刷新的状态private enum RefreshType: Int { // 下拉刷新状态 case normal = 0 // 松手就刷新 case pulling = 1 // 正在刷新 case refreshing = 2}// 自定义控件的高度private let RefreshControlHeight: CGfloat = 50// 自定义下拉刷新控件class RefreshControl: UIControl { // 记录当前刷新的控件 private var currentScrollVIEw: UIScrollVIEw? // 记录当前刷新状态 private var myRefreshType: RefreshType = .normal { dIDSet { switch myRefreshType { case .normal: print("下拉刷新") // 箭头重置,箭头显示,关闭风火轮,内容改成下拉刷新 pullDownImageVIEw.isHIDden = false UIVIEw.animate(withDuration: 0.25,animations: { // 重置箭头位置 self.pullDownImageVIEw.transform = CGAffinetransform.IDentity }) indicatorVIEw.stopAnimating() messageLabel.text = "下拉刷新" // 判断上一次刷新状态是正在属性,让重置默认位置 // oldValue 表示上一次存储的值 if oldValue == .refreshing { UIVIEw.animate(withDuration: 0.25,animations: { // 设置停留位置,核心代码,重置停留位置 self.currentScrollVIEw?.contentInset.top -= RefreshControlHeight }) } case .pulling: print("松手就刷新") // 箭头调转,内容修改成松手就刷新 UIVIEw.animate(withDuration: 0.25,animations: { // 调转箭头位置 self.pullDownImageVIEw.transform = CGAffinetransform(rotationAngle: CGfloat(M_PI)) }) messageLabel.text = "松手就刷新" case .refreshing: print("正在刷新") // 箭头隐藏,开启风火轮,内容改成正在刷新 pullDownImageVIEw.isHIDden = true // 开启风火轮 indicatorVIEw.startAnimating() messageLabel.text = "正在刷新..." UIVIEw.animate(withDuration: 0.25,animations: { // 设置停留位置,核心代码 self.currentScrollVIEw?.contentInset.top += RefreshControlHeight }) // 通知外界刷新数据 (核心代码) sendActions(for: .valueChanged) } } } // MARK: - 懒加载控件 // 下拉箭头图片 fileprivate lazy var pullDownImageVIEw: UIImageVIEw = UIImageVIEw(image: UIImage(named: "tablevIEw_pull_refresh")) // 下拉刷新内容 label fileprivate lazy var messageLabel: UILabel = { let label = UILabel() label.text = "下拉刷新" label.Font = UIFont.systemFont(ofSize: 11) label.textcolor = UIcolor.gray return label }() // 风火轮 fileprivate lazy var indicatorVIEw: UIActivityIndicatorVIEw = UIActivityIndicatorVIEw(activityIndicatorStyle: .gray) overrIDe init(frame: CGRect) { super.init(frame: frame) // 获取屏幕的宽度 let screenWIDth = UIScreen.main.bounds.size.wIDth // 设置 frame self.frame = CGRect(x: 0,y: -RefreshControlHeight,wIDth: screenWIDth,height: RefreshControlHeight) setupUI() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } // 添加控件设置约束 private func setupUI() { backgroundcolor = UIcolor.red // 添加子控件设置约束 addSubvIEw(pullDownImageVIEw) addSubvIEw(messageLabel) addSubvIEw(indicatorVIEw) // 使用系统布局 autolayout 需要关闭 autoresizing pullDownImageVIEw.translatesautoresizingMaskIntoConstraints = false messageLabel.translatesautoresizingMaskIntoConstraints = false indicatorVIEw.translatesautoresizingMaskIntoConstraints = false // 添加约束 addConstraint(NSLayoutConstraint(item: pullDownImageVIEw,attribute: .centerX,relatedBy: .equal,toItem: self,multiplIEr: 1,constant: -35)) addConstraint(NSLayoutConstraint(item: pullDownImageVIEw,attribute: .centerY,constant: 0)) addConstraint(NSLayoutConstraint(item: messageLabel,attribute: .leading,toItem: pullDownImageVIEw,attribute: .trailing,constant: 0)) addConstraint(NSLayoutConstraint(item: indicatorVIEw,constant: 0)) addConstraint(NSLayoutConstraint(item: indicatorVIEw,constant: 0)) } // 获取父控件,当前控件将要添加到那个父视图上面 overrIDe func willMove(toSupervIEw newSupervIEw: UIVIEw?) { print(newSupervIEw) // 判断是否是可以滚动的控件 if let scrollVIEw = newSupervIEw as? UIScrollVIEw { // 表示是 UIScrollVIEw 的子类,可以监听器滚动 // 可以使用 kvo 监听 contentOffSet 值得改变 // [.new,.old] 表示可以监听新值和旧值得改变 scrollVIEw.addobserver(self,forKeyPath: "contentOffset",options: .new,context: nil) // 记录刷新视图控件 currentScrollVIEw = scrollVIEw } } // kvo监听方法 overrIDe func observeValue(forKeyPath keyPath: String?,of object: Any?,change: [NSkeyvalueChangeKey : Any]?,context: UnsafeMutableRawPointer?) { guard let scrollVIEw = currentScrollVIEw else { return } // 代码执行到此,表示 scrollVIEw 不为 nil // 计算临界点 let maxY = -(scrollVIEw.contentInset.top + RefreshControlHeight) // 获取 y 轴偏移量 let contentOffSetY = scrollVIEw.contentOffset.y // 判断是否拖动 // 拖动情况下只有两种状态 .normal,pulling if scrollVIEw.isDragging { // 表示在拖动 判断的核心 if contentOffSetY < maxY && myRefreshType == .normal { myRefreshType = .pulling print("pulling") } else if contentOffSetY >= maxY && myRefreshType == .pulling { myRefreshType = .normal print("normal") } } else { // 表示松手,只有 pulling 状态 才能进入正在刷新 if myRefreshType == .pulling { myRefreshType = .refreshing print("正在刷新") } } } // 结束刷新 func endRefreshing() { myRefreshType = .normal } deinit { // 移除 kvo currentScrollVIEw?.removeObserver(self,forKeyPath: "contentOffset") } }
使用
// 自定义下拉刷新控件 fileprivate lazy var refreshControl: RefreshControl = RefreshControl() tableVIEw.addSubvIEw(refreshControl) refreshControl.addTarget(self,action: #selector(更新数据的方法名),for: UIControlEvents.valueChanged)总结
以上是内存溢出为你收集整理的Refresh for Swift全部内容,希望文章能够帮你解决Refresh for Swift所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)