SwiftUI 6.0(iOS 18.0)滚动视图新增的滚动阶段(Scroll Phase)监听功能趣谈

在这里插入图片描述

何曾几时,在 SwiftUI 开发中的秃头小码农们迫切需要一种能够读取当前滚动状态的方法。

在这里插入图片描述

在过去,他们往往需要借助于 UIKit 的神秘力量。不过这一切在 SwiftUI 6.0 中已成“沧海桑田”。

在本篇博文中,您将学到如下内容:

  • 1. ScrollView 滚动阶段简介
  • 2. 普度众生的 SwiftUI 6.0
  • 3. 滚动阶段更改上下文(ScrollPhaseChangeContext)
  • 4. 如何监听列表(List)的滚动阶段
  • 总结

相信学完本课后,小伙伴们在需要监听滚动视图滚动阶段的应用场景中定能得心应手、游刃有余!

那还等什么呢?让我们马上开始吧!Let‘s go!!!😃


1. ScrollView 滚动阶段简介

所谓滚动阶段(Scroll Phase)是指滚动视图在滚动前、滚动中以及滚动后所处的不同阶段。

早在 macOS 10.9+ 的 CoreGraphics 中就有滚动阶段的概念了:

在这里插入图片描述
在这里插入图片描述

如果我们能及时的读取各个滚动阶段的值,我们就可以根据它们为滚动视图提供更加“银杏化”的定制和更流畅滚动附加体验。

在 SwiftUI 6.0 之前,我们无法使用行之有效的方法来读取滚动视图当前所处的滚动阶段,只有委身救助于 UIKit 的秉轴持钧。

然而,这一切在 SwiftUI 6.0 中有了翻天覆地的变化!

2. 普度众生的 SwiftUI 6.0

自从 SwiftUI 6.0(iOS 18.0)开始,“顿悟”的苹果终于提供滚动阶段的监听功能了。

一方面,我们有了描述滚动阶段的新类型 ScrollPhase:

在这里插入图片描述

它包含 5 个枚举值分别对应于 5 种滚动阶段:

@frozen public enum ScrollPhase : Equatable {case idlecase trackingcase interactingcase deceleratingcase animatingpublic var isScrolling: Bool { get }
}

这些滚动阶段的含义如下所示:

  • Idle - 表示当前滚动视图处于空闲状态,可以认为“嘛事没有”;
  • Tracking - 表示当前用户正轻触滚动视图但并没有开始滚动;
  • Interacting - 表示用户正在开始或继续滚动着视图的内容;
  • Decelerating -表示用户已结束滚动操作,滚动视图的滚动正在减速直至静止状态;
  • Animating - 表示滚动视图被 ScrollPosition 或 ScrollViewReader 类型通过代码动态滚动到了指定的位置;

另一方面,我们有了新的视图改器方法 onScrollPhaseChange 专注于滚动阶段的监听:

在这里插入图片描述

有了以上两者的珠联璧合,现在我们在 SwiftUI 6.0 即可轻而易举的监听任何滚动视图的滚动阶段啦:

struct ContentView: View {var body: some View {ScrollView {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()Divider()}}.onScrollPhaseChange { old, new inguard old != new else { return }print("new phase: \(new)")}}
}

在 Xcode 16beta 中运行效果如下所示:

在这里插入图片描述

ScrollPhase 类型还提供一个 isScrolling 计算属性,我们可以用它来判断当前是否正在滚动。比如,假若视图正在被滚动我们就“遮挡”它的显示内容:

struct ContentView: View {@State var isScrolling = falsevar body: some View {ScrollView {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()Divider()}.redacted(reason: isScrolling ? .placeholder : [])}.onScrollPhaseChange { old, new inguard old != new else { return }print("正在滚动?\(new.isScrolling)")isScrolling = new.isScrolling}}
}

执行效果如下图所示:

在这里插入图片描述

3. 滚动阶段更改上下文(ScrollPhaseChangeContext)

除此之外,SwiftUI 6.0 中新增的 onScrollPhaseChange 修改器还提供另一种重载(Overloading)形式,在该重载方法的闭包中我们会得到一个 ScrollPhaseChangeContext 上下文对象,使用它我们可以更多的掌控滚动的其它全局信息:

在这里插入图片描述

nonisolated
func onScrollPhaseChange(_ action: @escaping (ScrollPhase, ScrollPhase, ScrollPhaseChangeContext) -> Void) -> some View

演示代码如下所示,可以看到在其中我们使用 ScrollPhaseChangeContext 上下文对象打印出了更多的与滚动相关的信息:

struct ContentView: View {        var body: some View {ScrollView {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()Divider()}        }.onScrollPhaseChange { old, new, context inguard old != new else { return }print("\(new)\n\(context)")            }}
}

运行结果如下所示:

在这里插入图片描述

ScrollPhaseChangeContext(geometry: <ScrollGeometry: contentOffset (0.0, 1694.3333333333333), contentSize (393.0, 4092.0), contentInsets <top: 59.0, leading: 0.0, bottom: 34.0, trailing: 0.0>, containerSize (393.0, 759.0), visibleRect (0.0, 1694.3333333333333, 393.0, 852.0)>, velocity: Optional((0.0, 0.0)))

4. 如何监听列表(List)的滚动阶段

虽然 SwiftUI 6.0 破茧而出的“大杀器” onScrollPhaseChange 对于我们监听滚动状态大有裨益,不过目前它只能应用在 ScrollView 视图的外层。这意味着,如果将其放在 List 上将会“徒劳无功”:

struct ContentView: View {        var body: some View {List {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()}        }.onScrollPhaseChange { old, new, context inguard old != new else { return }print("\(new)\n\(context)")}}
}

上述代码附着在 List 之上的 onScrollPhaseChange 修改器回调闭包将会无所事事,直接沦为“不舞之鹤”。

诚然我们可以使用 ScrollView 来平替 List,不过如果能在 List 上直接监听滚动阶段岂不更妙?

在 iOS 18.0beta 中,我们可以通过将 List 包裹在 Form 容器中暂时绕开此问题:

struct ContentView: View {        var body: some View {Form {List {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()}}}.onScrollPhaseChange { old, new, context inguard old != new else { return }print("\(new)\n\(context)")}}
}

运行代码可以看到,我们用 onScrollPhaseChange 修改器成功的捕获到了 List 中滚动阶段的改变以及其它滚动信息:

在这里插入图片描述

我不确定这一情况在 iOS 18.0 正式版中是否能够修复,让我们拭目以待吧!

总结

在本篇博文中,我们介绍了 SwiftUI 6.0(iOS 18.0)滚动视图最新的滚动阶段(Scroll Phase)监听功能,并讨论了如何在原本不支持该功能的列表(List)上使用它。

感谢观赏,再会啦!😎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/41740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一份适合新手的软件测试练习项目

最近&#xff0c;不少读者托我找一个能实际练手的测试项目。开始&#xff0c;我觉得这是很简单的一件事&#xff0c;但当我付诸行动时&#xff0c;却发现&#xff0c;要找到一个对新手友好的练手项目&#xff0c;着实困难。 我翻了不下一百个web网页&#xff0c;包括之前推荐练…

nginx的知识面试易考点

Nginx概念 Nginx 是一个高性能的 HTTP 和反向代理服务。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力在同类型的网页服务器中表现较好。 Nginx 专为性能优化而开发&#xff0c;性能是其最重要的考量指标&#xff0c;实现上非常注重效率&#…

C#用链表和数组分别实现堆栈

1.链表 实现栈的四个基本功能 入栈 出栈 长度 栈顶值 public class 基础 : MonoBehaviour {public class MyStack{//定义每一个元素的数据结构 //下一个元素 和 该元素的值public class StackData{public StackData next;public object data;public StackData(StackData next,…

linux驱动编程 - kfifo先进先出队列

简介&#xff1a; kfifo是Linux Kernel里面的一个 FIFO&#xff08;先进先出&#xff09;数据结构&#xff0c;它采用环形循环队列的数据结构来实现&#xff0c;提供一个无边界的字节流服务&#xff0c;并且使用并行无锁编程技术&#xff0c;即当它用于只有一个入队线程和一个出…

nginx修改网站默认根目录及发布(linux、centos、ubuntu)openEuler软件源repo站点

目录 安装nginx配置nginx其它权限配置 安装nginx dnf install -y nginx配置nginx whereis nginxcd /etc/nginx llcd conf.d touch vhost.conf vim vhost.conf 命令模式下输入:set nu或:set number可以显示行号 复制如下内容&#xff1a; server {listen 80;server_name…

【0294】Postgres内核 dynahash 之 hash_search 实现原理

相关文章: 【0289】Postgres内核之哈希表(Hash Tables) 【0290】Postgres内核之dynahash(动态哈希表,dynamic hash tables)(概念篇) 【0291】Postgres内核之dynahash table 创建 【0292】Postgres内核源码之dynahash 插入entry实现 【0293】Postgres内核之创建 dynahas…

ESP32 通过蓝牙显示歌词代码示例

通过蓝牙协议播放音乐&#xff0c;有的时候需要显示歌词&#xff0c;这里就是a2dp库获取了歌词 值得注意的是要想正确获取到歌词&#xff0c;必须打开各种播放器的字幕&#xff08;歌词&#xff09;开关 本项目用了三个开源库 a2dp&#xff0c;tft_espi,xfont. a2dp &#x…

基于python实现的监听服务接口是否正常,发送异常消息到钉钉群

获取钉钉机器人 创建钉钉群组(要求至少三个成员)进入群组 设置>机器人>添加机器人选择自定义机器人 按照要求填写完获取到 Webhook的链接 实现代码 from time import sleep import requests import json from datetime import datetime import logging# 配置日志记录的…

数据结构第11节: B树

B树是一种自平衡的树数据结构&#xff0c;它能够保持数据排序&#xff0c;并且在插入、删除和查找操作中具有对数时间复杂度。B树广泛应用于文件系统、数据库和索引中&#xff0c;因为它们可以有效地处理大量数据。 B树的特点&#xff1a; 所有叶子节点都位于同一层。每个节点…

【】AI八股-神经网络相关

Deep-Learning-Interview-Book/docs/深度学习.md at master amusi/Deep-Learning-Interview-Book GitHub 网上相关总结&#xff1a; 小菜鸡写一写基础深度学习的问题&#xff08;复制大佬的&#xff0c;自己复习用&#xff09; - 知乎 (zhihu.com) CV面试问题准备持续更新贴 …

.net 调用海康SDK的跨平台解决方案

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔序言 上2篇海康SDK使用以及常见的坑…

PCL 点云PFH特征描述子

点云PFH特征描述子 一、概述1.1 概念1.2 算法原理一、代码实现二、结果示例一、概述 1.1 概念 点特征直方图PFH(Point Feature Histograms)描述子:用于表示点云中每个点的局部几何形状信息,它是一种直方图描述子,包括了点云的法线方向和曲率信息,PFH描述子可以帮助区分不同…

深入Django(八)

掌握Django的管理后台 引言 在前七天的教程中&#xff0c;我们介绍了Django的基础架构、模型、视图、模板、URL路由、表单系统以及数据库迁移。今天&#xff0c;我们将深入了解Django的管理后台&#xff0c;这是一个功能强大的内置管理界面&#xff0c;用于创建、更新、查看和…

【JavaEE精炼宝库】文件操作(1)——基本知识 | 操作文件——打开实用性编程的大门

目录 一、文件的基本知识1.1 文件的基本概念&#xff1a;1.2 树型结构组织和目录&#xff1a;1.3 文件路径&#xff08;Path&#xff09;&#xff1a;1.4 二进制文件 VS 文本文件&#xff1a;1.5 其它&#xff1a; 二、Java 操作文件2.1 方法说明&#xff1a;2.2 使用演示&…

QT面试笔记总计

一 Qt 保证多线程安全? 使互斥锁保证多线程安全性。QMutex类、。使用读写锁保证多线程安全性&#xff0c;QReadWriteLock。使用信号和槽机制保证多线程安全性。使用显示切换保证多线程安全性。QTread类。 Qt 中的事件与信号的区别? 事件与信号的实现机制不同&#xff1b;事…

HCIA综合实验

学习新思想&#xff0c;争做新青年。今天学习的是HCIA综合实验&#xff01; 实验拓扑 实验需求 总部&#xff1a; 1、除了SW8 SW9是三层交换机&#xff0c;其他交换机均为2层交换机。 2、GW为总部的出口设备&#xff0c;使用单臂路由技术&#xff0c;VLAN10,20,100的网关都在GW…

ERROR: “armeabi-v7a“ not supported for HarmonyOS

IDE 从 devecostudio-mac-4.1.3.700 升级至 devecostudio-mac-5.0.3.403 后抛出了如下异常: ERROR: "armeabi-v7a" not supported for HarmonyOS. 解决办法 一.entry/build-profile.json5 需 entry/build-profile.json5 的 abiFilters 中移除 "armeabi-v7a&qu…

计算机网络体系结构详解:协议与分层

在学习计算机网络时&#xff0c;理解网络协议与分层体系结构是至关重要的。本文将详细介绍这些概念&#xff0c;帮助基础小白快速入门。 1. 什么是网络协议 网络协议是计算机网络中用于数据交换的规则和标准。这些规则规定了数据格式、时序以及发送和接收数据时的动作。网络协…

Unity3D瓦片地图辅助定位工具

介绍 该工具用于TileMap的瓦片辅助定位&#xff0c;通过键盘或鼠标按瓦片尺寸0到1的比例作为单次移动值移动定位点游戏对象。当采用定位点游戏对象映射瓦片时&#xff0c;可使用该工具来移动定位点游戏对象&#xff0c;在新版本Unity3D的TileMap编辑器中可使用GameObject Brush…

基于java+springboot+vue实现的流浪动物管理系统(文末源码+Lw)277

摘 要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&#xff0c;对流浪动物信息管理的提升&…