自定义下拉刷新渐变动画

作者: shineDeveloper | 来源:发表于2016-11-11 10:36 被阅读227次

    实现思路

    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地址下载

    相关文章

      网友评论

        本文标题:自定义下拉刷新渐变动画

        本文链接:https://www.haomeiwen.com/subject/owqfpttx.html