SwiftUI中ScrollViewReader的使用(自动滚动ScrollView)

ScrollViewReader是我最喜欢的SwiftUI新版本的新功能之一。在iOS 14发布之前,控制ScrollView的滚动位置并不容易。如果希望滚动视图滚动到特定位置,我们必须找到自己的解决方案。

使用ScrollViewReader,只需几行代码,就可以使滚动视图滚动到特定位置。本篇文章,我们将探究一下ScrollViewReader的使用。

关于ScrollView的使用,想必大家都不陌生了,先看一下下面这个示例:

struct ScrollViewReaderDemo: View {var body: some View {ScrollView {ForEach(0..<50) { index inText("This is item \(index)").font(.headline).frame(height: 150).frame(maxWidth: .infinity).background(Color.white).cornerRadius(10).shadow(radius: 10).padding()}}}
}

在这里插入图片描述
上面是一个比较简单的ScrollView使用方法,我们可以手动滑动界面。如果我们想要代码控制滚到哪里,或者是满足某个条件后,自动滚动,那如何处理呢,以前在UIKit中,我们能持有UIScrollView的实例变量,然后调用相关方法,那么在SwiftUI中有这么一个实例变量吗?

答案是肯定有的,那就是使用ScrollViewReader

ScrollViewReader是通过使用代理来滚动到已知的子视图,从而提供程序化滚动的视图。
ScrollViewReader的构造闭包里面返回了一个ScrollViewProxy类型的实例对象,通过这个对象调用scrollTo(_:anchor:)方法实现滚动。

func scrollTo<ID>(_ id: ID,anchor: UnitPoint? = nil
) where ID : Hashable

id: 子视图的唯一标识。
anchor: 滚动动作的对齐行为。

如果anchor为nil,则此方法会找到已标识视图,并滚动最小值以使已标识视图完全可见。
如果anchor非nil,它将定义已标识视图和滚动视图中要对齐的点。例如,将anchor设置为top将标识视图的顶部与滚动视图的顶部对齐。类似地,将anchor设置为bottom将标识视图的底部与滚动视图的底部对齐,依此类推。

下面的代码中,添加了一个Button,点击后将ScrollView滚动指定的位置,尤其要注意的是记得给每个子视图添加id修饰符,要不然滚动的时候就找不到指定视图了。

struct ScrollViewReaderDemo: View {var body: some View {ScrollViewReader { proxy inScrollView {Button("Scroll to specific item") {withAnimation{proxy.scrollTo(30, anchor: .bottom)}}ForEach(0..<50) { index inText("This is item \(index)").font(.headline).frame(height: 150).frame(maxWidth: .infinity).background(Color.white).cornerRadius(10).shadow(radius: 10).padding().id(index)}}}}
}

在这里插入图片描述
上面的代码能够轻松的实现ScrollView的滚动,ScrollViewReader闭包返回的proxy代理了ScrollView,进而操作滚动,问题来了,proxy的作用域只在ScrollViewReader闭包内,如果点击滚动的按钮在外面,或者在导航栏上,那该如何实现呢?

struct ScrollViewReaderDemo: View {@State private var scrollToIndex: Int?var body: some View {NavigationStack {ScrollViewReader { proxy inScrollView {ForEach(0..<50) { index inText("This is item \(index)").font(.headline).frame(height: 150).frame(maxWidth: .infinity).background(Color.white).cornerRadius(10).shadow(radius: 10).padding().id(index)}}.onChange(of: scrollToIndex) { newValue inif let newValue {withAnimation {proxy.scrollTo(newValue, anchor: .top)}}}}.navigationTitle("Title").navigationBarTitleDisplayMode(.inline).toolbar(content: {ToolbarItem(placement: .topBarTrailing) {Button("Scroll") {scrollToIndex = 30}}})}}
}

在这里插入图片描述
上面代码中将点击滚动的按钮放到了导航栏的右侧,这个时候在Button的点击事件内已经访问不到proxy代理了。
虽然访问不到了,但是我们可以通过一个状态变量(@State修饰的变量)的变化来触发滚动。

@State private var scrollToIndex: Int?

然后在能访问到proxy代理的区域内监听scrollToIndex的变化,然后滚动视图。代码中给ScrollView添加了onChange修饰符,并添加观察对象scrollToIndex,当scrollToIndex变化的时候onChange修饰符闭包会被触发,并返回最新的scrollToIndex的值。

.onChange(of: scrollToIndex) { newValue inif let newValue {withAnimation {proxy.scrollTo(newValue, anchor: .top)}}
}

Button的事件里面修改scrollToIndex的值即可。

.toolbar(content: {ToolbarItem(placement: .topBarTrailing) {Button("Scroll") {scrollToIndex = 30}}
})

通过这种方法就实现了外部点击,内部ScrollView滚动的效果了。当然后,上面代码只是提供了一个实现外部触发滚动的参考,具体还得看大家的业务和设计需求了。

另外ScrollViewReader也可以和List组合使用,滚动List

写在最后

ScrollViewReaderSwiftUI框架的一个很好的补充。现在无需开发自己的解决方案,就可以轻松地指示任何滚动视图滚动到特定位置。

最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

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

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

相关文章

Linux学习—Linux环境下的网络设置

在当今的数字化时代&#xff0c;网络配置是任何系统管理员和开发者必须掌握的技能之一。Linux操作系统以其灵活性和强大的网络功能而闻名&#xff0c;本文将带你深入了解Linux环境下的网络配置&#xff0c;并通过代码示例展示如何进行基本的网络设置。 Linux网络基础 Linux网…

使用opencv在图像上画带刻度线的十字线,以图像中心点为0点

使用OpenCV在图像上绘制带刻度线的十字线,可以通过以下步骤实现。我们将首先找到图像的中心点,然后绘制水平和垂直线,并在这些线的适当位置绘制刻度线。以下是详细的C++代码示例: #include<opencv2\opencv.hpp> //画十字标注线带刻度线,以图像中心点为0点 void Dra…

SD NAND(贴片式TF卡)坏块管理技术问答

Q1:什么是NAND的块(Block))? 每个Nand包含一个或多个Chip。Chip是可以独立执行命令并上报状态的最小单元。 每个Chip包含一个或多个plane。不同的plane间可以并发操作&#xff0c;不过有一些限制。 每个plane包含多block&#xff0c;block是最小擦除单元&#xff08;擦除后为…

一文了解如何安全有效的进行PB级别的大数据迁移

在这个信息量爆炸的时代&#xff0c;处理PB级别的数据转移已成为常态&#xff0c;但对企业而言&#xff0c;这仍然是一个充满挑战的任务。今天&#xff0c;我们来探讨一下这个话题&#xff0c;看看在进行PB级数据转移时&#xff0c;需要留意哪些事项&#xff0c;可能会遇到哪些…

B端数据看板,其实数据可以更美的。

B端数据看板可以通过设计来提升其美观度。 色彩和配色方案&#xff1a; 选择适合品牌和数据类型的色彩搭配方案。使用渐变色、明亮的色调和对比度来突出重要的数据指标。 数据可视化&#xff1a; 使用图表、图形和数据图像来呈现数据&#xff0c;使其更易于理解和解读。选择…

报考PMP机构,主打一个听劝

近期PMP报考着实是火了一把&#xff0c;看到身边很多的朋友都考了PMP&#xff0c;搞得我心头痒痒的&#xff0c;后来了解了一下大家报考PMP的初衷&#xff0c;大家都是为了自我提升和升职加薪&#xff0c;有的人拿到PMP证书已经实现了升职加薪了。身边的朋友都劝我去考PMP证书&…

基于STC89C52单片机空气PM2.5系统设计资料

#include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char //宏定义sbit RSP1^6;//液晶接口sbit ENP1^7;sbit LED P2^0;//粉尘传感器控制接口sbit ADCS P3^7;//AD0832接口sbit ADCLK P3^5;sbit ADDI P3^6;sbit ADDO P3^6;…

线性dp+数论分块,1561D1 - Up the Strip

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1561D1 - Up the Strip (simplified version) 二、解题报告 1、思路分析 一眼dp 写出dp方程&#xff1a; 前者维护前缀和即可O(1)转移 后者呢&#xff1f;——整除分块数论分块问题-CSDN博客 简单叙述下…

Day15:二叉树层序遍历 LeedCode 102.二叉树的层序遍历 199二叉树的右视图 637.二叉树的层平均值 101.对称二叉树 226.翻转二叉树

详细讲解,点击跳转 102. 二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3]…

防病毒克星——白名单可信系统

白名单作为一种网络安全措施&#xff0c;其核心概念在于限制用户只能访问网络所有者定义的受信任内容。这种机制在保护系统免受恶意软件、病毒等攻击方面发挥着重要作用。然而&#xff0c;关于白名单是否可以防病毒的问题&#xff0c;实际上涉及了多个方面的考虑。 首先&#x…

解决uboot编译multiple definition of yylloc报错

编译u-boot时报错&#xff1a;multiple definition of yylloc 解决办法&#xff1a;找到源码目录下的script/dtc/dtc-lexer.l文件&#xff0c;第41行&#xff0c;用extern修饰一下yylloc 即可解决

使用ros订阅图像话题并保存成图像

下载代码后&#xff0c;修改: conda环境视频保存路径图像话题 使用&#xff1a;运行后&#xff0c;在终端输入start并回车开始录制&#xff0c;输入stop并回车结束录制。 #!/home/cvpr/anaconda3/envs/ros_py37/bin/python3.7 # -*- coding: utf-8 -*-""" 订…

Java装饰器模式,装饰器模式通常通过创建一个接口和一个或多个实现了该接口的类来开始,然后创建装饰器类,这些类也实现了相同的接口

1、定义一个接口Component public interface Component { void operation(); }2、创建一个实现了Component接口的简单类SimpleComponent public class SimpleComponent implements Component { Override public void operation() { System.out.println("SimpleCom…

SD8055单节锂电池完整恒流线性充电器USB电源充电循环

SD8055是一款用于单节锂离子电池的完整恒流/恒压 线性充电器。其ThinSOT封装和较低的外部元件数量 使SD8055非常适合便携式应用。此外&#xff0c;SD8055是s特 定的 可在USB电源规格范围内工作由于内部MOSFET结构 &#xff0c;不需要外部感测电阻&#xff0c;也不需要阻塞二极管…

如何在 Mac 上使用 Windows 版 Excel 的全部功能

作为 Mac 用户&#xff0c;你是否怀念 Excel 的一些关键功能&#xff1f;是不是在 Mac 版 Excel 中找不到全面的 VBA、Active X 和表单控件、智能标签、Power Pivot 等关键工具&#xff1f;Mac 用户们&#xff0c;其实你不必错过这些功能。终极解决方案就是&#xff1a;通过 Pa…

CR80通用清洁卡:证卡打印机、ATM机、POS机、读卡器等卡片设备清洁维护的好助手!

随着科技的进步&#xff0c;ATM机、POS终端、门禁系统、证卡打印机、读卡器等卡片设备在我们的日常生活中扮演着越来越重要的角色&#xff0c;些设备在长时间使用和环境因素的影响下&#xff0c;容易积聚油脂、灰尘和其他污染物&#xff0c;从而对其性能和功能产生负面影响。 深…

外企跨国大数据迁移的注意事项

跨国数据迁移&#xff0c;对汽车行业来说&#xff0c;是一桩大事。跨国公司在进行这一操作时&#xff0c;会遇到不少挑战&#xff0c;比如网络延迟、数据安全、成本控制等等。今天&#xff0c;咱们就聊聊跨国大数据迁移中&#xff0c;跨国车企需要留意的几个关键点。 跨国大数据…

重学java 64.IO流 字符流

Action speak louder than words —— 24.6.5 字符输入流 一、字节流读取中文的问题 1.注意&#xff1a; 字节流是万能流&#xff0c;这个万能更侧重于文件复制&#xff0c;但是尽量不要边读边看 2.原因&#xff1a; UTF-8&#xff1a;一个汉字占三个字节 GBK&#xff1a;一…

ufw防火墙基本操作

ufw防火墙基本操作 ufw防火墙的基本操作包括以下几个方面&#xff1a; 安装ufw&#xff1a; 在Ubuntu系统上&#xff0c;可以使用以下命令安装ufw&#xff1a;sudo apt-get update 和 sudo apt-get install ufw。 启动、停止和检查状态&#xff1a; 启动防火墙&#xff1a;su…

IO流-----各种流(对象流,内存流,打印流,随机访问流)

各种流 各种流&#xff1a;对象流&#xff1a;操作&#xff1a;对象输入输出流&#xff1a;写入数据&#xff1a;读取数据&#xff1a; 内存流&#xff1a;内存输出流&#xff1a;内存输入流&#xff1a; 打印流&#xff1a;字节打印流&#xff1a;字符打印流&#xff1a; 随机…