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,一经查实,立即删除!

相关文章

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 即可解决

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

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

如何在 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;一…

linux和 qnx 查看 网卡网络流量

netstat -i netstat -i和-s-CSDN博客

Windows 2000 Server:安全配置终极指南

"远古技术&#xff0c;仅供娱乐" &#x1f4ad; 前言&#xff1a;Windows 2000 服务器在当时的市场中占据了很大的比例&#xff0c;主要原因包括操作简单和易于管理&#xff0c;但也经常因为安全性问题受到谴责&#xff0c;Windows 2000 的安全性真的那么差吗&#x…

虹科免拆诊断案例 | 2013 款路虎神行者 2 车偶发性无法起动

故障现象 一辆2013款路虎神行者2车&#xff0c;搭载2.0 L Si4 Petrol发动机&#xff0c;累计行驶里程约为4.5万km。车主反映&#xff0c;车辆偶发性无法起动&#xff0c;故障出现时&#xff0c;尝试起动发动机&#xff0c;组合仪表上会出现“挡位不在驻车挡”“充电系统故障”…

【阿里云】在云服务器ECS 安装MySQL、本地远程连接或宝塔连接(手动部署)

目录 一、安装MySQL 二、配置MySQL 三、远程访问MySQL数据库 四、Navicat本地连接远程MySQL 五、宝塔连接MySQL 如果你是使用宝塔安装的MySQL请绕过&#xff0c;以下是通过命令行模式&#xff08;手动部署&#xff09;进行安装、配置及运行。 安装&#xff1a;MySQL8.0 …

【golang学习之旅】Go中的cron定时任务

系列文章 【golang学习之旅】报错&#xff1a;a declared but not used 【golang学习之旅】Go 的基本数据类型 【golang学习之旅】深入理解字符串string数据类型 【golang学习之旅】go mod tidy 【golang学习之旅】记录一次 panic case : reflect: reflect.Value.SetInt using…

Python编程学习第一篇——制作一个小游戏休闲一下

到上期结束&#xff0c;我们已经学习了Python语言的基本数据结构&#xff0c;除了数值型没有介绍&#xff0c;数值型用的非常广&#xff0c;但也是最容易理解的&#xff0c;将在未来的学习中带大家直接接触和学习掌握。后续我们会开始学习这门语言的一些基础语法和编程技巧&…