自定义下拉刷新渐变动画

实现思路

1.用ta b le view指定了刷新的内容区域,当下拉刷新时,若超出了table的内容的空白区域,系统会自动弹回内容的原位置。因此可以将刷新的vie w放在scrollview的上面

2.随着用户的滚动更新refresh vie w中的内容,根据用户向下拉动的远近来改变view背景色,视差滚动

3.用户松开结束滚动时,应该进行一次判断,判断用户是否要刷新页面。因为刷新将伴随着网络下载。只有当滚动到足够距离的时候,才认为是下拉刷新。
此时才回锁定到刷新的页面,并让其保持可见的状态。做动画的处理

此时心中会有一些问题

如何追踪用户的滚动进度?

*refreshview的可见区域的高度= content offset.y - contentInset.top.y

上代码

1.准备工作要注意的地方,我用图片进行展示


创建的类别
创建的类别
视图控制器.png
导航控制器.png
ui tableview ce l l.png

2.创建刷新的视图:RefreshView.swift
`private unowned var scrollView : UIScrollView //unowened相当于o c的weak

init(frame : CGRect, scrollView : UIScrollView) {
    self.scrollView = scrollView;
    super.init(frame: frame)
    backgroundColor = UIColor.green
    
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

`

让刷新视图相应用户下拉的操作
当用户下拉table的时候会响应系统的一个通知,因此会响应scrollviewdidscroll方法

下拉刷新的渐变效果核心代码如下:

//在refreshviewcontroller中
override func scrollViewDidScroll(_ scrollView: UIScrollView) { //把通知传递给refreshview,让他进行相应的变化 refreshView.scrollViewDidScroll(scrollView: scrollView) }

//在refresh view 中

` func updateBackgroundColor() {
backgroundColor = UIColor(white: 0.7*progress + 0.2, alpha: 1.0)
}

func scrollViewDidScroll(scrollView: UIScrollView) {
    //刷新视图可见的区域
    let refreshHeight = max(0,  -scrollView.contentOffset.y - scrollView.contentInset.top)
    //场景的高度
    progress = min(1, refreshHeight/kSceneHeight)
    
    //根据进度来改变背景色
    updateBackgroundColor()
    
}`

视差滚动,即界面中的所有控件的动画,以不同的速度进行移动时,产生的立体的效果

确定一个动画需要知道控件的起始位置,结束位置,路径
它们之间的关系是 起始位置的y值 = 结束位置的y值 + 移动速率*场景的高度

创建一个工具类RefreshIterm.swift来处理动画的路径
`private var centerStart: CGPoint
private var centerEnd: CGPoint
unowned var view: UIView

//起始位置
init(view: UIView, centerEnd: CGPoint, parallaxRatio: CGFloat, sceneHeight: CGFloat) {
    self.view = view
    self.centerEnd = centerEnd
    centerStart = CGPoint(x: centerEnd.x, y: centerEnd.y + (parallaxRatio * sceneHeight))
    self.view.center = centerStart
}

//跟据下拉的进度确定控件的位置
func updateViewPositionForPercentage(percentage: CGFloat) {
    view.center = CGPoint(
        x: centerStart.x + (centerEnd.x - centerStart.x) * percentage,
        y: centerStart.y + (centerEnd.y - centerStart.y) * percentage)
}`

在refresh view中加载做动画的控件
`func setupRefreshItems() {
let groundImageView = UIImageView(image: UIImage(named: "ground"))
let buildingsImageView = UIImageView(image: UIImage(named: "buildings"))

    refreshItems = [
        RefreshIterm(view: buildingsImageView, centerEnd: CGPoint(x: bounds.midX,
                                                                  y: bounds.height - groundImageView.bounds.height - buildingsImageView.bounds.height / 2), parallaxRatio: 1.5, sceneHeight: kSceneHeight),
        RefreshIterm (view: groundImageView,
                                 centerEnd: CGPoint(x: bounds.midX,
                                                    y: bounds.height - groundImageView.bounds.height/2),
                                 parallaxRatio: 0.5, sceneHeight: kSceneHeight),
        
    ]
    
    for refreshItem in refreshItems {
        addSubview(refreshItem.view)
    }
}`

控件滚动的时候,改变控件的位置

func updateRefreshItemPositions() { for refreshItem in refreshItems { refreshItem.updateViewPositionForPercentage(percentage: progress) } }

自定义动画的刷新和锁定,通过判断用户是不是拉的足够远来决定是否要执行刷新的操作

首先声明一个de le ga te属性,在声明一个是否刷新的状态变量isrefreshing

开始刷新,调用UI view的animateWithDuration方法,将scrollview的contentins e t加上上场景的高度

出发刷新,首先不是正在刷新,下拉的进度最大时 ,触发刷新。

触发代理使控制器进行刷新操作

核心代码:
` func beginRefreshing() {
isRefreshing = true

    UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: { () -> Void in
        self.scrollView.contentInset.top += kSceneHeight
    }) { (_) -> Void in
    }
}`

func endRefreshing() { UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: { () -> Void in self.scrollView.contentInset.top -= kSceneHeight }) { (_) -> Void in self.isRefreshing = false } }

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { if !isRefreshing && progress == 1 { beginRefreshing() // -scrollView.contentInset.top delegate?.refreshViewDidRefresh(refreshView: self) } }

运行效果为:

Untitled.gif

demo地址下载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,274评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,982评论 4 60
  • 今日凌晨三点半左右,雷声轰鸣,一场大雨不期而至。雷声不断,雨声不停,我辗转反侧到五点十多分起床整理笔记。到七点,雨...
    筱阿诚阅读 179评论 1 0
  • 还记得上小学的时候,每逢寒暑假爸爸都交代让我和弟弟制定学习计划,必不可少的两项就是练字和画画,基本都是临摹,只...
    葫芦宝贝阅读 321评论 0 3
  • 1你认为最完美的快乐是怎样的? 我认为最完美的快乐是能够畅所欲言,做自己真正想做的事情,不会因为外界的各种束缚而做...
    继续海阔天空阅读 208评论 0 1