iOS开发笔记>> 下拉刷新,自定义UIControl
来源:互联网 发布:阿里云 oss cdn https 编辑:程序博客网 时间:2024/05/21 10:11
自定义下载刷新分析:
1. 系统的下拉刷新 UIRefreshControl , 没有继承系统的下拉刷新, 而继承UIControl
2. 自定义UIControl, 系统的下拉刷新默认有宽和高, 自定义的时候在init构造函数中设置固定的宽和高和y值
3. 添加子控件(菊花, 文字一些控件)设置约束
4. 下拉刷新线索: contentOffset. y值发生变化时, 对应的效果才会变化
5. 使用KVO监听 contentOffset 这个属性值的改变
6. 把监听方法移动到自定义的UIControl里
7. 分析下拉刷新的三种状态: 正常状态, 释放状态, 加载数据状态
8. 结合 contentOffset. y 和 UISrollView的dragging 这个属性来分析临界值
9. 记录这个状态值得改变, 分别实现对应的效果
10. 优化 - 用一个标记来排除状态的多次改变(这里用的是枚举)
11. 根据效果遇到一些小bug:
1. 加载中的时候视图下沉一下
2. 加载数据需要调用UIControl 的 sendActionsForControlEvents 方法
3. 实现一下加载完成后恢复视图的问题
下面直接上swift的代码(OC的话思路是一样的)
自定义CNRefreshView
//// CNRefreshView.swift// Sina//// Created by 晟楠 on 16/5/4.// Copyright © 2016年 晟楠. All rights reserved.//import UIKit// 记录状态的枚举enum CNRefreshStatus: Int { /// 正常状态 case Nomal = 1 /// 释放去加载数据状态 case pulling = 2 /// 加载数据状态 case loading = 3 }class CNRefreshView: UIControl { /// UIScrollView类型的属性 var scrollView: UIScrollView? /// 记录状态的属性 var status: CNRefreshStatus = .Nomal { didSet { // 统一处理事件 switch status { case .Nomal: messageLable.text = "下拉刷新" UIView.animateWithDuration(0.25, animations: { () -> Void in // 恢复箭头 self.arrowImageView.transform = CGAffineTransformIdentity }) // 显示箭头 arrowImageView.hidden = false // 停止菊花转动 loadingView.stopAnimating() // 隐藏菊花 loadingView.hidden = true case .pulling: messageLable.text = "释放刷新" // 旋转箭头 UIView.animateWithDuration(0.25, animations: { () -> Void in self.arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI)) }) case .loading: messageLable.text = "加载中" UIView.animateWithDuration(0.25, animations: { () -> Void in // 让加载的view停留一下 var inset = self.scrollView!.contentInset inset.top = inset.top + 50 self.scrollView?.contentInset = inset }) // 隐藏箭头 arrowImageView.hidden = true // 菊花开启 loadingView.startAnimating() // 菊花显示 loadingView.hidden = false // 是加载数据状态要去加载数据 // 根据事件去触发方法 sendActionsForControlEvents(UIControlEvents.ValueChanged) } } } // MARK: - 1.重写父类构造函数 // 需要制定布局 override init(frame: CGRect) { super.init(frame: frame) // 添加子控件和设置子控件约束 setUpUI() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } // MARK: 子控件添加到父控件上回调用此方法 override func willMoveToSuperview(newSuperview: UIView?) { super.willMoveToSuperview(newSuperview) printLog(newSuperview) // 转换成UIScrollView, 集成UIScrollView的子类都可以用 if newSuperview is UIScrollView { scrollView = newSuperview as? UIScrollView // MARK: - KVO监听tableView的contentOffset scrollView?.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New, context: nil) } } // MARK: - 实现KVO要监听的方法 override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { // 判断dragging进行更改标记 if scrollView!.dragging { if scrollView?.contentOffset.y < -140 && status == .Nomal { status = .pulling } else if scrollView?.contentOffset.y >= -140 && status == .pulling { status = .Nomal } } else { if scrollView?.contentOffset.y < -140 && status == .pulling { status = .loading } } } // MARK: - 数据加载完成后调用 func endRefreshing() { if status == .loading { // 让视图位置恢复 UIView.animateWithDuration(0.25, animations: { () -> Void in // 停留一下view var inset = self.scrollView!.contentInset inset.top = inset.top - 50 self.scrollView?.contentInset = inset }) } // 修改标记回到正常状态 status = .Nomal } // MARK: 2.添加子控件和设置子控件约束 private func setUpUI() { // 自定义子控件 backgroundColor = UIColor.clearColor() // 设置宽高 var frame = self.frame frame.size = CGSizeMake(kUIScreenWidth, 50) frame.origin.y = -50 self.frame = frame // 添加控件 addSubview(arrowImageView) addSubview(messageLable) addSubview(loadingView) // 设置约束 loadingView.snp_makeConstraints { (make) -> Void in make.centerX.equalTo(self.snp_centerX).offset(-30) make.centerY.equalTo(self.snp_centerY) } arrowImageView.snp_makeConstraints { (make) -> Void in make.centerX.equalTo(self.snp_centerX).offset(-30) make.centerY.equalTo(self.snp_centerY) } messageLable.snp_makeConstraints { (make) -> Void in make.centerY.equalTo(self.snp_centerY) make.left.equalTo(arrowImageView.snp_right).offset(-5) } } // MARK: 3. 懒加载控件 // 箭头 private lazy var arrowImageView: UIImageView = { let img = UIImageView() img.image = UIImage(named: "tableview_pull_refresh") return img }() // 菊花 private lazy var indicatorImageView: UIImageView = { let img = UIImageView() img.image = UIImage(named: "tableview_loading") return img }() // 提示语 private lazy var messageLable: UILabel = { let lable = UILabel() lable.text = "下拉刷新" return lable }() private lazy var loadingView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)}控制器CNHomeTableViewController, 只需要做懒加载, 监听, 添加即可
// 下拉刷新 private lazy var refreshView: CNRefreshView = CNRefreshView()
// 添加下拉刷新视图 tableView.addSubview(refreshView)
// 监听refreshView,当refreshView是加载数据时调用loadData refreshView.addTarget(self, action: "loadData", forControlEvents: UIControlEvents.ValueChanged)
// 停止下拉刷新 self.refreshView.endRefreshing()
代码如有哪里不妥可以加关注私信或评论给我, 谢谢
0 0
- iOS开发笔记>> 下拉刷新,自定义UIControl
- ios下拉刷新笔记
- iOS开发 ----- 下拉刷新
- iOS 下拉刷新-自定义
- UIControl-IOS开发
- IOS开发之UIControl
- UIControl-IOS开发
- UIControl-IOS开发
- iOS开发---MJRefresh下拉刷新/下拉加载
- iOS:自定义下拉刷新视图和下拉刷新原理
- iOS-自定义MJRefresh下拉刷新动画
- ios 表格 实现自定义下拉刷新
- iOS笔记-(利用EGORefreshTableHeaderView自定义上拉加载和下拉刷新)
- iOS 开发基础UIControl事件
- iOS下拉刷新和上拉刷新(自定义)
- 【iOS开发】---- 下拉刷新(附Demo)
- IOS开发——TabelView下拉刷新
- iOS 开发:上拉加载,下拉刷新
- IOCP不可忽视的细节
- 项目管理十大知识领域和五大过程
- android recyclerview 删除和添加 bug
- easy sssp(spfa判断负环)
- Opencv的Mat型
- iOS开发笔记>> 下拉刷新,自定义UIControl
- Asyncsocket 使用总结
- HashCode
- 动感的网页相册
- 精选CSDN的ACM-ICPC五星博客
- 1881: 蛤玮的机房(今天不宜AC)
- Android-BroadcastReceiver使用笔记
- 黑皮书杂谈
- 带进位的右移