用Swift实现淘宝和大众点评的下拉刷新

来自Leo的原创博客,转载请著名出处

我的StackOverflow

我的Github

https://github.com/LeoMobileDeveloper


效果

淘宝

大众点评


项目地址

其中

  • 大众点评的下拉刷新用了50行左右代码
  • 淘宝的下拉刷新用了90行左右代码

完整的代码地址:PullToRefreshKit

Tips:用Swift 2.2写的,所以需要XCode 7.3来运行。


PullToRefreshKit

这是我用纯Swift 2.2写的一个库,初衷是为了更简单的实现自定义下拉刷新。当然,它也支持一代码实现:上拉加载,左/右滑动加载更多的操作。

比如,用一行代码实现默认的下拉刷新

self.tableView.setUpHeaderRefresh { [weak self] in
   delay(1.5, closure: {
        self?.tableView.endHeaderRefreshing(.Success)
   })
}

效果

不过,这个库的主要目的还是希望大家能方便的实现自定义刷新界面,不管是哪个方向的。

通过它来自定义刷新界面,只需要实现三个协议中的一个。

比如,实现自定义下拉刷新,只需写一个UIView的子类,要遵循协议RefreshableHeader。这个UIView的子类,你可以用AutoLayout,任何你想要使用的布局效果。

这个协议有如下几个方法

//拖拽的触发刷新的距离,也是Header的高度
func distanceToRefresh()->CGFloat

//拖拽或者释放的时候,比例的变化。比如总高度是100,当拖拽为10的时候,比例就是0.1,在这里,可以根据百分比动态的设置Header的状态
func percentUpdateWhenNotRefreshing(percent:CGFloat)

//松手即将进入刷新状态的回调,在这里,把视图切换为动画状态
func releaseWithRefreshingState()

//刷新结束,将要开始隐藏Header的动画,在这里告诉用户刷新失败或者成功
func didBeginEndRefershingAnimation(result:RefreshResult)

//刷新结束,Header完全隐藏的回调,这里把Header恢复到最初的状态
func didCompleteEndRefershingAnimation(result:RefreshResult)   

大众点评下拉刷新

分析一下,大众点评的下拉刷新主要分为两个状态

  • 下拉的过程中,根据下拉程度,动态调整显示的图片
  • 刷新的时候,显示动图

首先,我们准备好图片,本文的图片来自于MJ哥的MJRefresh

其中,下拉的过程的图片,一共有60张,刷新的时候,动图有3张。

这60张图是不一样的,比如第一张,第1,30,60张如下,下拉的过程就是不断的切换图片

至于刷新的过程中,就是用Imageview,动态播放以下三张图片罢了

所以,代码如下

class DianpingRefreshHeader:UIView,RefreshableHeader{
    let imageView = UIImageView()
    //放置Imageview
    override init(frame: CGRect) {
        super.init(frame: frame)
        imageView.frame = CGRectMake(0, 0, 60, 60)
        imageView.center = CGPointMake(CGRectGetWidth(self.bounds)/2.0, CGRectGetHeight(self.bounds)/2.0 + 10)
        addSubview(imageView)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    // MARK: - RefreshableHeader -
    //一共的距离是70
    func distanceToRefresh()->CGFloat{
        return 60
    }
    //监听百分比变化,切换图片
    func percentUpdateWhenNotRefreshing(percent:CGFloat){
        imageView.hidden = (percent == 0)
        let adjustPercent = max(min(1.0, percent),0.0)
        let scale = 0.2 + (1.0 - 0.2) * adjustPercent;
        imageView.transform = CGAffineTransformMakeScale(scale, scale)
        let mappedIndex = Int(adjustPercent * 60)
        let imageName = "dropdown_anim__000\(mappedIndex)"
        let image = UIImage(named: imageName)
        imageView.image = image
    }
    //松手即将刷新,播放动图
    func releaseWithRefreshingState(){
        let images = ["dropdown_loading_01","dropdown_loading_02","dropdown_loading_03"].map { (name) -> UIImage in
            return UIImage(named:name)!
        }
        imageView.animationImages = images
        imageView.animationDuration = 0.6
        imageView.startAnimating()
    }
    //刷新结束,将要隐藏header,不做任何处理
    func didBeginEndRefershingAnimation(result:RefreshResult){

    }
    //刷新结束,完全隐藏header,恢复到最初状态
    func didCompleteEndRefershingAnimation(result:RefreshResult){
        imageView.animationImages = nil
        imageView.stopAnimating()
        imageView.hidden = true
    }
}

然后,这样调用

  let dianpingHeader = DianpingRefreshHeader(frame: CGRectMake(0,0,CGRectGetWidth(self.view.bounds),60))
  self.tableView.setUpHeaderRefresh(taobaoHeader) { [weak self] in
        delay(1.5, closure: {
            self?.tableView.endHeaderRefreshing(.Success)
        })
    }

淘宝下拉刷新

首先分析视图架构

整个下拉刷新的界面如下

其中

  1. 是CAShapeLayer,随着滑动,动态调整绘制过程,刷新的时候转圈圈
  2. 是CAShapeLayer,静态的,当刷新的时候隐藏
  3. 简单的UILabel

所以,完整的代码如下

class TaoBaoRefreshHeader:UIView,RefreshableHeader{
    private let circleLayer = CAShapeLayer()
    private let arrowLayer = CAShapeLayer()
    private let textLabel = UILabel()
    private let strokeColor = UIColor(red: 135.0/255.0, green: 136.0/255.0, blue: 137.0/255.0, alpha: 1.0)

    override init(frame: CGRect) {
        super.init(frame: frame)
        setUpCircleLayer()
        setUpArrowLayer()
        textLabel.frame = CGRectMake(CGRectGetWidth(self.bounds)/2 - 30, CGRectGetHeight(self.bounds)/2 - 20,120, 40)
        textLabel.textAlignment = .Center
        textLabel.textColor = UIColor.lightGrayColor()
        textLabel.font = UIFont.systemFontOfSize(14)
        textLabel.text = "下拉即可刷新..."
        self.addSubview(textLabel)
    }
    //绘制中间箭头
    func setUpArrowLayer(){
       //略去
    }
    //绘制外部圆圈
    func setUpCircleLayer(){
        //略去
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

// MARK: - RefreshableHeader -
    func distanceToRefresh()->CGFloat{
        return 60
    }
    //根据滑动百分比,动态调整storkeEnd和文字
    func percentUpdateWhenNotRefreshing(percent:CGFloat){
        let adjustPercent = max(min(1.0, percent),0.0)
        self.circleLayer.strokeEnd = 0.05 + (0.95 - 0.05) * adjustPercent
        if adjustPercent  == 1.0{
            textLabel.text = "释放即可刷新..."
        }else{
            textLabel.text = "下拉即可刷新..."
        }
    }
    //进入刷新状态,调整圈圈的strokeEnd,为圈圈增加旋转动画,更新label文字
    func releaseWithRefreshingState(){
        self.circleLayer.strokeEnd = 0.95
        let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
        rotateAnimation.toValue = NSNumber(double: M_PI * 2.0)
        rotateAnimation.duration = 0.6
        rotateAnimation.cumulative = true
        rotateAnimation.repeatCount = 10000000
        self.circleLayer.addAnimation(rotateAnimation, forKey: "rotate")
        self.arrowLayer.hidden = true
        textLabel.text = "刷新中..."
    }
    //结束刷新的动画开始,停止动画
    func didBeginEndRefershingAnimation(result:RefreshResult){
        self.circleLayer.removeAllAnimations()
    }
    //Header完全隐藏,恢复到原始状态
    func didCompleteEndRefershingAnimation(result:RefreshResult){
        self.circleLayer.strokeEnd = 0.05
        self.arrowLayer.hidden = false
        textLabel.text = "下拉即可刷新"

最后

如果你喜欢这个库,欢迎和我一起把它完善,PullToRefreshKit ,欢迎各种建议,Star,fork。

时间: 2024-10-16 23:39:33

用Swift实现淘宝和大众点评的下拉刷新的相关文章

Listview嵌套Viewpager实现仿淘宝搜狐广告主页,并实现listview的下拉刷新

Android实现功能:Listview嵌套viewpager仿淘宝搜狐视频主页面,和listview的下拉刷新. 什么都不说了:直接上图说效果 listview嵌套viewpager实现仿淘宝的广告滑动主页面 源码连接:(http://download.csdn.net/detail/qq_30000411/9528977) APK下载连接:(http://download.csdn.net/detail/qq_30000411/9528973) 下面给出我源码的主要文件构成: MyListV

[iOS] 使用UIRefreshControl 实现 UITableView下拉刷新(Swift版本)

首先,在viewDidLoad中初始化相关数据: override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. //添加刷新 refreshControl.addTarget(self, action: "refreshData", forControlEvents: UIControlEvents.ValueChanged) refreshCon

iOS 下拉刷新和加载更多 (OC\Swift)

Swift语言出来之后, 可能还没有第三方的下拉刷新和上提加载, 所以自己用UIRefreshControl控件和UITableView实例的tableFooterView(底部视图)属性结合起来写了一个下拉刷新和点击加载更多的基本实现, 分为OC的代码实现和Swift的代码实现, 希望大家可以指出不足: Swift代码: 1 import UIKit 2 3 class ViewController: UITableViewController { 4 5 // 用于显示的数据源 6 var

仿淘宝商品浏览界面, 向上拉查看详情

最新项目中有展示类似淘宝商品详情的功能,主要实现  向上拉查看详情,百度一搜,发现有大神已经实现这个效果了 http://blog.csdn.net/zhongkejingwang/article/details/38656929 写的很棒.用2个ScrollView 实现上拉查看详情的功能 可是发如今用在我的项目有点问题,有些小的需求没有实现,所以就在这位大神的基础上加入了简单的功能 1. 事件回调.   第二页全然显示出来的回调,能够用来载入数据 2. 事件回调.   当用户滑到第一个Scr

swift详解之十九--------------UITableView的基本操作(下拉刷新,新增删除,分组,检索等)

UITableView的基本操作(下拉刷新,新增删除,分组,检索等) 注:本小结总结UITableview的一些基本用法 UITbleView继承自UIScrollView,只能用来显示一列数据(目前就只认识到这里),纵向滑动. 一般有两种方式来实现,直接用UITableViewController , 占满整个屏幕 .不用手动实现UITableViewDataSource 和UITableViewDelegate .另一种方式在UIViewController 中.我们看看这种方式 let t

网红淘宝店的成与败

近年来,随着直播的人气火热上升,越来越多的网红出现在我们的眼前.很多人都想成为网红,为什么呢?因为他们有人气,有喜欢自己的粉丝,而他们能通过这些粉丝和人气来获取利益,例如通过自己的人气接广告或卖东西给喜欢自己的粉丝.这就是为什么淘宝里有越来越多的网红店,他们通过自身的人气效应给自己打广告,在直播或博客中秀出自己店里的商品. 想要了解网红淘宝店的成与败,我们先来谈论网红淘宝店的运营方式.网红淘宝店当然老板是网红,但其实在幕后有一个操作团体,他们不仅起到封装网红的作用,还帮他们进货出货,网红只要负责

淘宝村、网红小镇……扎堆的互联网产业有那么美好吗

国人最大的爱好之一,似乎就是喜欢跟风.扎堆.不仅仅是现实生活中扎堆看热闹,更体现在社会的方方面面.尤其是一个又一个的"风口",更是让企业和创业者趋之若鹜.从团购.电商,到智能手机.O2O,再到手游.共享经济.直播--层出不穷的"扎堆"迅速改变着社会架构和大众的生活方式. 而在近日,中国第一座网红小镇"DAMARAVILLAGE颜值·艺术小镇"正式对外亮相.这意味着,直播行业不仅仅是平台扎堆,更是完成了在线下的落地和扎堆.结合此前国内为数不少的淘宝

阿里巴巴资产分析报告: 淘宝和天猫谁更赚钱?

1. 在此次阿里巴巴 IPO 资产中,核心业务依然是 C2C 淘宝和 B2C 天猫.天猫去年的交易额增长或为 100%,淘宝则可能低于 40%: 2. 淘宝.天猫和聚划算的营收模式并不相同,主体上是通过收取营销费用.广告费和佣金: 3. 阿里巴巴与京东分别代表"平台电商自营化"和"自营电商平台化"两种模式,彼此渗透,未来竞争取决于精细化作业能力. 关于阿里上市,那些清楚的和糊涂的 阿里巴巴集团与北京时间 5 月 7 日向美国证券交易委员会(SEC)提交了招股说明书(

(淘宝无限适配)手机端rem布局详解

一.        首先我们先来看看淘宝不同分辨率下的适配页面 可以看出来,淘宝在不同的分辨率下,页面的尺寸和模块间的间距会发生变化,这是因为淘宝采用了rem,这篇文章会简单介绍淘宝的布局思路以及具体做法,不过在此之前我们先了解一些移动端的知识,以为更好的理解淘宝布局的方案,下面我们来看一些移动端的知识 二.了解一些移动端的知识viewport的<meta>标签用法 其主要用来告诉浏览器如何规范的渲染Web页面,而你则需要告诉它视窗有多大 移动端开发中,通常我们都会采用<meta nam