使用 Lottie 自定义 UIRefreshControl

2024-03-30

我的目标是替换默认的微调器UIRefreshControl与洛蒂动画。

我的问题是,当我拉下动画时,动画不会立即播放UICollectionView其子视图是UIRefreshControl。仅当我稍微向下滚动并暂停手指时才会播放动画。当我再次开始移动滚动位置时,它立即返回到其初始开始状态,不播放。

任何指导将不胜感激,下面是相关代码..

func setupRefreshControl() {
    guard let refreshContents = Bundle.main.loadNibNamed("RefreshControlView", owner: self, options: nil), let refreshView = refreshContents[0] as? RefreshControlView else { return }

    refreshView.frame = refreshControl.frame
    refreshControl.addSubview(refreshView)

    refreshControl.tintColor = UIColor.clear
    refreshControl.backgroundColor = UIColor.clear
    refreshControl.addTarget(self, action: #selector(exampleFunction), for: .valueChanged)      
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    for subview in refreshControl.subviews {
        if let refreshControlView = subview as? RefreshControlView {
            refreshControlView.activityIndicatorControl.animationView.setAnimation(named: "lottieJson")                
            refreshControlView.activityIndicatorControl.animationView.loopAnimation = true
            refreshControlView.activityIndicatorControl.animationView.play()
            break
        } else {
            continue
        }
    }
}

滚动时看不到动画播放,因为每次scrollViewDidScroll被称为你通过调用重新启动动画play。而且由于在滚动时该函数几乎不断被调用,因此动画没有机会播放超过第一帧的内容。所以看起来暂停了。

实现自定义刷新控件时,您必须实现 3 个阶段:

1、用户滚动但尚未触发刷新

在此阶段,您可能希望根据用户滚动的距离来显示动画的进度。为此,您需要计算进度scrollViewDidScroll并将其传递给LOTAnimationView's animationProgress财产。

要计算此进度,您必须知道用户必须向下滚动多远才能触发刷新。根据我的经验,这发生在contentOffset.y大约为150.

2.触发刷新

当用户向下滚动足够长的距离时.valueChangedControlEvent 被触发。发生这种情况时,您可以通过调用来启动循环动画play() on the LOTAnimationView

3.刷新完成

当刷新完成后你调用endRefreshing()在您的自定义刷新控件上。发生这种情况时,您可以通过调用来停止动画stop() on the LOTAnimationView

查看我在一个项目中使用的 LottieRefreshControl 的小示例:

import UIKit
import Lottie

class LottieRefreshControl: UIRefreshControl {
fileprivate let animationView = Lottie.AnimationView(name: "searchAnimation")
fileprivate var isAnimating = false

fileprivate let maxPullDistance: CGFloat = 150

override init() {
    super.init(frame: .zero)
    setupView()
    setupLayout()
}

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

func updateProgress(with offsetY: CGFloat) {
    guard !isAnimating else { return }
    let progress = min(abs(offsetY / maxPullDistance), 1)
    animationView.currentProgress = progress
}

override func beginRefreshing() {
    super.beginRefreshing()
    isAnimating = true
    animationView.currentProgress = 0
    animationView.play()
}

override func endRefreshing() {
    super.endRefreshing()
    animationView.stop()
    isAnimating = false
}
}

private extension LottieRefreshControl {
func setupView() {
    // hide default indicator view
    tintColor = .clear
    animationView.loopMode = .loop
    addSubview(animationView)

    addTarget(self, action: #selector(beginRefreshing), for: .valueChanged)
}

func setupLayout() {
    animationView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        animationView.centerXAnchor.constraint(equalTo: centerXAnchor),
        animationView.centerYAnchor.constraint(equalTo: centerYAnchor),
        animationView.widthAnchor.constraint(equalToConstant: 50),
        animationView.heightAnchor.constraint(equalToConstant: 32)
    ])
}
}

现在你只需要打电话updateProgress在刷新控件上scrollViewDidScroll:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    refreshControl.updateProgress(with: scrollView.contentOffset.y)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Lottie 自定义 UIRefreshControl 的相关文章

随机推荐

  • 使用退格控制字符擦除

    我正在尝试使用退格控制字符 b 删除行尾的尾随逗号 尽管它在没有其他输出的情况下有效stdout 如果之后有另一个输出 b 它变得毫无用处 这是一个例子 include
  • OpenCV2 薄板样条应用变换不起作用?

    我正在使用 Python OpenCV2 实现薄板变压器并遇到一些问题 当我执行 WarpImage 时 图像会正确扭曲 但是当我使用一些手动输入的点的estimateTransformation 时 这些点无法正确映射 相反 所有点最终都
  • Python 将列重塑为多列 - 交替行

    任何人都可以建议一种有效的方法 将一列 在 python pandas 数据框中 重塑为多列 并交替进行列分配 我可以用循环来做到这一点 但想知道是否有更优雅的方法 例如 请考虑以下示例 Added 有没有人有一个解决方案 可以将单列中的每
  • 如何比较两个日期?

    我有三个日期 1 上一个日期 2 当前日期 3 下一个日期 我想检查 currentDate 是否晚于前一个日期且早于 nextDate 我怎么做 NSDateFormatter df NSDateFormatter alloc init
  • Haskell 函数 :: [名称] -> [[(Name, Bool)]]

    鉴于以下情况 type Name String envs Name gt Name Bool 我必须实现 envs 以便给定名称列表 它返回名称和布尔值的所有可能组合 我的尝试没有返回所有可能的组合 这是我的代码 envs xxs x xs
  • 如何确保 Jest 在“unhandledRejection”上失败?

    我们的单元测试在持续交付管道的容器中运行 有时 我们不会在单元测试中处理拒绝 但是 我认为这是不正确的 并且在我看来管道应该失败 我怎样才能确保当我执行时jest并且在测试期间unhandledRejection事件发生 jest 会错误退
  • 提示工具包和提示工具包有什么区别

    我最近运行了一个 conda 列表 我发现我有两个不同的软件包 分别称为prompt toolkit 3 0 4 和prompt toolkit 3 0 4 我试图用谷歌搜索它们之间的区别 基本上使用我的问题标题的确切措辞 而出现的只是pr
  • 在javascript中获取鼠标光标的大小

    我需要确定网页上当前使用的鼠标光标的宽度和高度 我需要在光标正下方显示一个 div 也可能在其右侧 所以我需要确定 div 相对于确切指针位置的偏移量 这样光标就不会覆盖 div 该机制将用于Intranet系统 因此它可以是仅firefo
  • Terraform 中使用多个 user_data 文件

    我正在尝试为常见任务 例如文件夹创建和某些包安装 提供一个通用的 user data 文件 并为应用程序特定的配置提供一个单独的 user data 文件 我正在尝试以下 user data data template file userd
  • MacOS,如何删除键盘快捷键中未使用的服务项

    我是 Mac OS 的新手 正在学习 Automator 我发现它很有用 但不太可控 我在服务中创建了快捷方式 但不知道如何删除它 突出显示的项目是我要删除的项目 我想我应该用 Automator 来做 但我不知道如何做 任何帮助将不胜感激
  • javascript闭包立即评估[重复]

    这个问题在这里已经有答案了 考虑以下 JavaScript 代码 var a var f function for var i 0 i lt 3 i a push function alert i for var j 0 j lt 3 j
  • 如何使用 Haskell Aeson 解析数组

    我有一个 JSON 文档 如下所示 series 1 2 2 3 3 4 我想将其解析为一组数据类型 data Series Series DataPoint data DataPoint DataPoint Int Int x and y
  • 为什么我的 MongoDB $or 查询不起作用?

    我正在尝试执行 or 搜索来匹配两个正则表达式 如下所示 metadata text or regex hello regex world 我正在使用 mlab com 并收到以下错误 MongoDB error Command faile
  • 使用twig变量动态调用导入的宏子函数

    我正在尝试是否使用变量来调用特定的宏名称 我有一个正在导入的宏文件 import form elements html twig as forms 现在该文件中包含所有表单元素宏 文本 文本区域 选择 单选等 我有一个传入的数组变量 其中包
  • Groovy 相对于 Jython 或 Jruby 的优势?

    当我可以使用 Jython 或 Jruby 时 为什么我要选择使用 Groovy 该语言是否提供了任何固有的优势来弥补 Jython 和 Jruby 技能适用于 JVM 之外的其父语言的事实 请记住 我故意保持这个问题的通用性 但如果特定领
  • 为什么灯光出现在对面?

    我正在尝试使用构建照明this https learnopengl com Lighting Basic Lighting教程 但是 灯光出现在人体物体的错误一侧 我不知道为什么 法线是按三角形创建的 三角形的顶点基本上具有相同的法线 gl
  • 如何让 Spring XD 在启动时部署一组预定义的流和 Tap

    有没有办法在启动 spring xd 的新实例时启动一组已定义的 steam 和 tap 场景是这样的 我们已经在开发系统上完成了一些原型设计 但现在我们想要构建并将其发布给测试团队 我们希望自动化大部分后台工作 用户只需担心流的输出 而不
  • 为具有特定标题的通用狮身人面像警告定义标记

    我正在使用 Sphinx 为 Python 程序生成 HTML 文档 我想使用generic admonition http docutils sourceforge net docs ref rst directives html gen
  • 简单会员资格:用户上次登录日期

    我在我的 asp net MVC 4 应用程序中使用简单成员资格 我如何获取用户的上次登录日期 我没有看到默认网页架构表中创建的日期 我是否需要在简单会员资格中创建 LastLogin 日期字段 谢谢 我已经这样解决了 我在 UsersCo
  • 使用 Lottie 自定义 UIRefreshControl

    我的目标是替换默认的微调器UIRefreshControl与洛蒂动画 我的问题是 当我拉下动画时 动画不会立即播放UICollectionView其子视图是UIRefreshControl 仅当我稍微向下滚动并暂停手指时才会播放动画 当我再