SwiftUI中List的样式及使用详解(添加、移动、删除、自定义滑动)

SwiftUI中的List可是个好东西,它用于显示可滚动列表的视图容器,类似于UITableView。在List中可以显示静态或动态的数据,并支持垂直滚动。List是一个数据驱动的视图,当数据发生变化时,列表会自动更新。
针对List,我们还可以进行添加、移动、删除以及滑动等功能。

显示静态数据

显示静态的数据还是比较简单的,比如要显示12个月份:
在这里插入图片描述
上面代码中,直接在List组件里面放置Text组件即可,不过如果同类型数据过多,还是采用动态数组的方式去显示。

显示动态数据

很多的时候采用的都是动态数组显示的方式,比如通过网络请求回来的数据,再通过List显示出来等等。
在这里插入图片描述
上面的代码简化了很多,我们将months数据作为第一个参数,传给了List,而List的第二个参数id,则表示months数据中的元素采用自身作为唯一的标识符。如果数组中的两个或多个元素不是唯一的,这可能会导致问题。

如果不用字符串数据,而是该用了实例对象数组,则可以将实例对象的结构实现Identifiable协议,该协议需要实现一个id属性,如果将一个实现了Identifiable协议的实例对象数组传给List,则不需要指定id参数了。比如下面的代码示例:
在这里插入图片描述

样式设置

默认的List是有背景色,Light模式下是白色,Dark模式下是灰色,比如下面这个代码:
在这里插入图片描述

背景色
只需要添加一行代码即可,将其修饰在List闭包内部的组件上,即修饰在Text组件上。如果直接修饰在List组件上,则没有任何效果。

.listRowBackground(Color.blue)

在这里插入图片描述

内间距
另外上面的代码中,Text的宽度没有完全和cell的宽度对齐,两边还有一些间距,有的时候是不需要这个间距的,设置下面代码即可,同样是要修饰在List闭包内的组件上。

.listRowInsets(EdgeInsets())

在这里插入图片描述
分割线颜色与隐藏
设置分割线以及是否显示需要将下面两个修饰符作用在List闭包内的组件上。

// 隐藏分割线,默认是显示的。
.listRowSeparator(.hidden)
// 设置分割线颜色。
.listRowSeparatorTint(.red)

设置Cell之间的间距
默认cell之间是采用分割线进行区分的,如果设置间距,则分割线直接就隐藏了。

.listRowSpacing(10)

该修饰符需要作用在List组件上,效果如下图,设置了10个间距。
在这里插入图片描述
List样式
设置List样式可以通过下面的代码设置:

.listStyle()

括号内需要传入对应的style参数。listStyle修饰符需要作用在List组件上。

  1. automatic:默认列表样式,根据设备和环境自动选择合适的列表样式。
  2. plain:普通列表样式。
  3. grouped:分组列表样式。
  4. insetGrouped:缩进分组列表样式。
  5. sidebar:侧边栏列表样式。
  6. inset:缩进列表样式。

以上样式的效果图如下,有些样式不太明显,结合其他的修饰符效果可能更好。
在这里插入图片描述

分组显示(Section、 Header、 Footer)

List组件要想实现分组的功能,很简单,在List组件中使用Section组件即可。Section组件支持HeaderFooter功能,同时HeaderFooter也支持直接设置Title和自定义。

比如下面直接设置Section title的示例,直接给Title一个字符串,在content闭包内通过ForEach循环添加要显示的组件,当然也可以不用循环,而是静态数据。
在这里插入图片描述
下面是自定义HeaderFooter的示例,Header中横向显示了ImageText组件,Footer中添加了一个Text,效果如下:
在这里插入图片描述
这里额外说一下ListForEach循环的结合使用的场景:

  1. 如果只是单纯的显示一些静态数据,或者一个数据数据,只用List组件即可。
  2. 如果要显示数组数据,可以单独使用List组件,将数组数据传给List,也可以在List组件中添加ForEach组件,通过ForEach循环遍历数组数据。
  var body: some View {List {ForEach(fruits, id: \.self) { fruit inText(fruit.capitalized)}}}
  1. 如果即有静态数据又有动态数据要显示,则需ListForEach组合使用。
    在这里插入图片描述
    上面的代码稍微有些多,主要为了视觉效果更好一些。从效果图中可以看出是人为设置了两个Header,采用了Text组件,并设置了相关的属性修饰符。代码中不难看出List组件里面采用了ForEach,同时也单独设置了Text组件。

另外需要提一下,我们给ForEach设置了前景颜色,这个前景颜色会作用在ForEach中的每个Text上。还有给Group组件设置了List cell的样式,那么这个样式也会作用在List中的每个子组件上,这样做代码会更加简洁明了。

添加和删除元素

只能在List的动态部分添加和删除元素,而静态元素不能在应用程序运行时添加或删除。因此,我们的列表需要完全动态,或者至少包含一个动态部分,以便我们能够添加或删除元素。

为了有添加和删除的入口,我们添加了导航栏,并设置了导航栏的toolbar,导航栏的设置这里不过多阐述。

添加元素
在导航栏的右侧添加了一个添加元素的按钮,点击后在List要展示的数据中添加元素,此时也要求该数据必须被@State包裹修饰,以便其修改后触发UI刷新。具体代码见下面效果图。

删除元素
在导航栏左侧添加了一个EditButton,点击后将整个List设置为编辑模式,并在每个cell的左侧提供一个红色的删除按钮。这个过程主要是由系统自动的。不过前提是要对List添加至少一个可操作的方法,比如onDelete,onMove等,否则点击了EditButtonList也没有任何变化。
另外对单个cell进行左滑操作也可以删除元素。

为了实现删除效果,需要在ForEach上添加onDelete方法,如下:

.onDelete(perform: { indexSet in})

这个onDelete方法返回一个IndexSet类型的值,我们可以在这个闭包内进行数据删除,不过为了UI逻辑和业务逻辑低耦合,采用单独抽出来一个方法处理删除逻辑,如下:

func deleteItem(indexSet: IndexSet) {fruits.remove(atOffsets: indexSet)
}

deleteItem方法里面,fruits数组调用remove(atOffsets:)方法即可。

因为onDelete方法返回一个IndexSet类型的值,所以抽出来的方法同样接受这样类型的值。最终只要在ForEach上调用下面代码即可,不用额外写传递的参数。

ForEach(fruits, id: \.self) { fruit inText(fruit.capitalized)
}
.onDelete(perform: deleteItem)

最终代码及效果如下图:
在这里插入图片描述

移动功能

移动功能还是比较普遍的,基于上面的代码,只需要在ForEach上添加下面的方法即可。

.onMove(perform: { indices, newOffset in})

这个方法返回两个参数,第一个为IndexSet类型的值,第二个为Int类型的值。同onDelete一样,我们单独抽出来一个方法,同样接收这两个参数。

func moveItem(indexSet: IndexSet, offSet: Int) {fruits.move(fromOffsets: indexSet, toOffset: offSet)
}

moveItem方法中,fruits数据调用move(fromOffsets:, toOffset:)方法即可。最后在ForEach上添加该方法:

ForEach(fruits, id: \.self) { fruit inText(fruit.capitalized)
}
.onMove(perform: moveItem)

实现了上面的代码后,我们可以在List的编辑模式下拖动cell移动,编辑模式下每个cell右侧有三个横杠的图标,拖动即可移动。另外非编辑模式下长按cell后也可以进行拖动,代码及效果图如下:
在这里插入图片描述

自定义左滑功能

SwiftUIswipeActions()修饰符允许你添加一个或多个滑动动作按钮到你的列表行,可选地控制他们属于哪一边,以及他们是否应该被触发使用一个完整的滑动。
先看下代码及效果图:
在这里插入图片描述
swipeActions()方法有三个参数,第一个edge决定操作按钮放哪边;第二个allowsFullSwipe决定完全滑动是否自动执行第一个操作,默认值为true;第三个即是内容闭包了。

关于样式,只能通过tint设置背景色,如果不设置,系统默认是灰色的。
SwiftUI底层还是很聪明的,比如第一个Button,我们用Text显示内容,只有文字,那么系统就显示了Add文字,第二个和第三个用Label显示,有文字和图片,但是系统聪明的只显示了图片。

对于想要拥有删除功能的按钮,应该使用Button(role: .destructive),而不是仅仅指定一个红色背景色,比如上面第三个按钮,不需要有任何删除的逻辑,聪明的底层帮我们实现了。

Button(role: .destructive) {} label: {Label("Delete", systemImage: "trash.fill")
}

写在最后

SwiftUI中的List确实是一个非常好用的组件,包含的功能也比较多,大多数的App界面也都是由导航栏和List组成的。
本篇文章篇幅有点长,不过讲的也比较通俗易懂,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

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

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

相关文章

树莓派4B 有电但无法启动

试过多个SD卡,反复烧系统镜像都无法启动。接HDMI显示器没有信号输出,上电后PWR红灯长亮,ACT绿灯闪一下就不亮了,GPIO几个电源脚有电,芯片会发热,测量多个TP点电压好像都正常。 ……

华为造车布局全曝光,对标奔驰、迈巴赫等

文 | Auto芯球 作者 | 雷慢 这一刻,我承认我格局小了, 就在刚刚,余承东曝光了华为智选车的布局计划, 华为问界、智界、享界等,将全面对标奔驰、迈巴赫、劳斯莱斯等车系, 这布局,确实是世界…

揭秘《庆余年算法番外篇》:范闲如何使用维吉尼亚密码解密二皇子密信

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣! 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航: LeetCode解锁100…

【yolov10】使用自己的数据集训练目标检测模型

【yolov10】使用自己的数据集训练目标检测模型 一、anaconda安装二、环境配置三、数据集制作1、labelimg的安装2、使用labelimg 四、正片1、下载yolov10源码2、数据集目录3、训练4、推理 一、anaconda安装 直接参考前一篇博客: https://blog.csdn.net/m0_71523511/…

击穿盲点——【网络安全】社会工程学中的网络欺骗

社会工程学起源于上世纪60年代左右,是一种通过人际交流的方式来获得情报的非技术渗透手段。这种手段无需过多技术要求,却非常有效,目前已成为危害企业网络安全的重大威胁之一。著名黑客凯文米特尼克在《反欺骗的艺术》中曾提到,人…

SpringBoot+Vue开发记录(七)-- 跨域文件与Restful风格

本篇文章的主要内容是关于项目的跨域配置和给项目添加restful风格接口。 重点是文件粘贴 文章目录 一、 跨域二、Restful风格1. 什么是restful风格?2. 项目文件结构3. 新建文件4. 在Controller中进行修改 一、 跨域 跨域问题暂时也就那样,解决方法就是…

云计算-No-SQL 数据库 (No-SQL Database)

DynamoDB简介 (Introduction to DynamoDB) AWS DynamoDB 是亚马逊提供的一种 NoSQL 数据库,适用于需要快速访问的大规模应用程序。NoSQL 数据库指的是非关系型数据库(或许应该称为“非关系数据库”)。关系型数据库是你之前可能使用过的熟悉的…

深入Django项目实战与最佳实践

title: 深入Django项目实战与最佳实践 date: 2024/5/19 21:41:38 updated: 2024/5/19 21:41:38 categories: 后端开发 tags: Django 基础项目实战最佳实践数据库配置静态文件部署高级特性 第一章:Django项目架构与设计原则 Django框架概述 Django是一个高级的P…

Next.js里app和pages文件夹的区别

最近开始学 Next.js,因为纯自学,有时候网上找到的学习资料都是几年前的,难免会有点 outdated,因此当自己创建的项目结构和视频里呈现的结构不一致时,难免会有点困惑。 例如,今天遇到的第一个问题就是&…

CAD二次开发(2)-将直线对象添加到CAD图形文件

1. 准备工作 创建一个类库项目,如下: 2. 分析Line对象 Line类的初始化方法和参数 using Autodesk.AutoCAD.DatabaseServices; Line line new Line();Line 继承Curve 继承Entity 继承DBObject 继承Drawable 继承RXObject 初始化方法有两个&#xf…

大模型分布式训练并行技术分享

目前业内解决大模型问题,基本以多节点、分布式方案为主。分布式方案具体的实施时,又分为数据并行、参数并行、流水线并行等,针对具体的业务场景采取合适的并行方案方可带来更高的效率。 后续结合业内主流的分布式框架,具体介绍各种…

数据库(5)——DDL 表操作

表查询 先要进入到某一个数据库中才可使用这些指令。 SHOW TABLES; 可查询当前数据库中所有的表。 表创建 CREATE TABLE 表名( 字段1 类型 [COMMENT 字段1注释] ...... 字段n 类型 [COMMENT 字段n注释] )[COMMENT 表注释]; 例如,在student数据库里创建一张studen…

网络安全等级保护:正确配置 Linux

正确配置 Linux 对Linux安全性的深入审查确实是一项漫长的任务。原因之一是Linux设置的多样性。用户可以使用Debian、Red Hat、Ubuntu或其他Linux发行版。有些可能通过shell工作,而另一些则通过某些图形用户界面(例如 KDE 或 GNOME)工作&…

APP安全测试汇总【网络安全】

APP安全测试汇总 一.安装包签名和证书 1.问题说明 检测 APP 移动客户端是否经过了正确签名,通过检测签名,可以检测出安装包在签名后是否被修改过。如 果 APP 使⽤了 debug 进⾏证书签名,那么 APP 中⼀部分 signature 级别的权限控制就会失效…

Unity 生成物体的几种方式

系列文章目录 unity工具 文章目录 系列文章目录前言👉一、直接new的方式创建生成1-1.代码如下1-2. 效果图 👉二、使用Instantiate创建生成(GameObject)2-1.代码如下2-2.效果如下图 👉三.系统CreatePrimitive创建生成3…

数据结构之栈和队列(超详解

目录 一.栈 1.栈的基本概念 2.栈的基本操作 3.栈的储存结构 ①栈的顺序储存 (1)基本概念 (2)代码实现 ②栈的链式储存 (1)基本概念 (2)代码实现 二.队列 1.队列的基本概念 2.队列的基本操作 3.队列的储存结构 ①队列的链式储存 (1)基本概念 ​编辑 (2)代码实现 ②…

Spring MVC+mybatis 项目入门:旅游网(一)项目创建与准备

个人博客:Spring MVCmybatis 项目入门:旅游网(一)项目创建与准备 | iwtss blog 先看这个! 这是18年的文章,回收站里恢复的,现阶段看基本是没有参考意义的,技术老旧脱离时代(2024年辣…

从0开始学统计-卡方检验

1.什么是卡方检验? 卡方检验是一种用于检验观察频数与期望频数之间差异的统计方法。它通常用于分析分类变量之间的关联性或独立性。在卡方检验中,我们将观察到的频数与期望频数进行比较,从而确定它们之间的差异是否显著。 卡方检验的基本思…

【机器学习与大模型】驱动下的应用图像识别与处理

摘要: 本文深入探讨了机器学习在图像识别与处理领域的应用,特别是在大模型的推动下所取得的巨大进展。详细阐述了图像识别与处理的基本原理、关键技术,以及机器学习算法和大模型如何提升其性能和准确性。通过实际案例分析了其在多个领域的广泛…