当前位置: 首页 > news >正文

SwiftUI(十二)- 容器组件 布局与结构的基石


引言

在用户界面开发中,布局是设计一个应用程序的视觉层次和交互体验的核心之一。无论是设计简单的按钮排布,还是复杂的多层次页面,合理的布局和结构可以极大地提升用户体验。而容器组件,作为将多个视图整合、组织、排列的工具,是布局的关键。

UIKit中的容器:从ViewController到Stack View

在传统的UIKit框架中,我们通常使用UIViewController、UINavigationController等视图控制器来管理整个页面的声明周期和导航。此外,UIKit还提供了诸如UIStackView、UITabBarController等基础容器,用于管理视图的布局和排列:

  • UIViewController:管理视图的声明周期,是大部分页面的基本构建块。
  • UINavigationController:创建分层页面的导航结构,让用户可以通过“返回”按钮返回上一级视图。
  • UIStackView:提供水平或垂直排列视图的功能,并可以自动调整子视图的尺寸。
  • UITabbarController:用户构建底部标签栏导航,便于在多个功能模块之间切换。

这些容器为UIKit应用提供了灵活而强大的布局管理能力,但它们也带来了一些开发复杂性。UIKit需要我们手动管理视图的生命周期,常常要求使用约束或者是Frame进行精细的布局。

SwiftUI:声明式布局和简化的容器管理

SwiftUI的出现,带来了声明式编程的方式,使布局和视图管理更加直观。在SwiftUI中,容器不再是复杂的控制器,而是一些更为轻量级的组件,如NavigationView、TabView、Group、VStack等。这些容器组件不仅可以完成UIKit中相同的布局功能,还能提供更灵活的视图组合和管理:

  • 轻量化:SwiftUI中的容器组件更加轻量,无需管理视图的生命周期。
  • 声明式:开发者可以直接声明视图的布局,SwiftUI会根据代码自动渲染视图。
  • 动态响应:SwiftUI容器组件和布局会自动响应数据变化,实现即时更新界面。

在本篇博客中吗,我们将深入讨论SwiftUI中的核心容器组件,了解如何使用它们来构建灵活、动态的用户界面,从而实现高效的开发流程。希望通过这个介绍,能够帮助大家更好地理解容器的重要性,并为接下来的实践打下坚实基础。

NavigationView

NavigationView是SwiftUI中的层级导航容器,在开发一个多页面应用时,导航控制器是不可或缺的一部分。它让用户在不同页面间切换,并能返回上一页面。而在SwiftUI中,NavigationView就承担这种层级导航的组件。它简化了UIKit中的UINavigationController公共,并将其融入到声明式编程中,使导航变得更加直观。

在SwiftUI中NavigationView的基本用法如下:

主页面

struct ContentView: View {var body: some View {NavigationView {VStack {Text("主页面").padding(.bottom)NavigationLink(destination: DetailView()) {Text("跳转到详情页面")}}.padding().navigationTitle("主页")}}
}

详情页面

/// 详情页面
struct DetailView: View {var body: some View {Text("这是一个详情页面").navigationTitle("详情页")}
}

在这个例子中,我们直接使用NavigationLink包裹导航的视图,并指定目标视图为DetailView()。与UIKit不同,SwiftUI会自动管理导航的声明周期和页面的更新,这会带来以下优点:

  1. 简单声明:只需添加一个NavigationLink就能实现页面跳转,不再需要手动管理导航栈。
  2. 自动管理生命周期:SwiftUI会自动处理视图的加载和释放,避免了UIKit中常见的内存管理问题。
  3. 灵活的导航栏标题:使用.navigationTitle可以轻松设置页面标题,无需额外的代码。

TabView

TabView是SwiftUI中的多标签导航容器。在应用中,多标签导航是非常常见的一种布局方式,尤其适用于那些具有多个功能模块的应用。它通常出现在页面底部,方便用户在不同的页面或功能间切换。在SwiftUI中,TabView是用于实现这种标签导航的主要容器。

SwiftUI中的TabView实现如下:

TabView

struct TabViewContentView: View {var body: some View {TabView {HomeView().tabItem {Image(systemName: "house")Text("主页")}SearchView().tabItem {Image(systemName: "magnifyingglass")Text("搜索")}DynamicView().tabItem {Image(systemName: "person")Text("动态")}}}
}

主页

/// 首页
struct HomeView: View {var body: some View {NavigationView {VStack {Text("主页面").padding(.bottom)}.padding().navigationTitle("主页")}}
}

搜索

/// 搜索
struct SearchView: View {var body: some View {NavigationView {VStack {Text("搜索页面").padding(.bottom)}.padding().navigationTitle("搜索")}}
}

动态

/// 动态
struct DynamicView: View {var body: some View {NavigationView {VStack {Text("动态页面").padding(.bottom)}.padding().navigationTitle("动态")}}
}

在这个例子中,我们用.tabItem为每个视图指定了图标和标题,SwiftUI会自动将这些视图放入底部标签栏,用户可以轻松地在不同的视图间切换。

自定TabView样式

SwiftUI中的TabView不仅可以使用简单样式,还可以进行自定义样式。我们可以用.background、.accentColor等修饰符来调整整个标签栏的颜色。

        TabView {HomeView().tabItem {Image(systemName: "house")Text("主页")}SearchView().tabItem {Image(systemName: "magnifyingglass")Text("搜索")}DynamicView().tabItem {Image(systemName: "person")Text("动态")}}.accentColor(.red) // 设置标签选中的颜色.background(Color.black) // 设置背景颜色

动态设置标签内容

在SwiftUI中,我们还可以基于数据动态生成标签项,例如根据条件决定显示哪些标签。这在需要根据用户权限或者状态来显示不同标签时非常有用:

@State private var showProfile = trueTabView {HomeView().tabItem {Image(systemName: "house.fill")Text("首页")}if showProfile {ProfileView().tabItem {Image(systemName: "person.circle")Text("个人")}}
}

Group

Group是SwiftUI中的一个特殊容器。它不会对布局产生直接影响,也不会添加额外的视图层次、但它提供了一种灵活的方式将多个视图组合在一起。Group主要有以下几个作用:

  1. 避免子视图数量限制:在SwiftUI中,单个容器最多只能包含10个直接子视图,而Group可以帮助分割这些子视图,以避免子视图数量的限制。
  2. 结构化视图层次:在编写复杂布局时,Group让我们可以将视图分组,使代码更有条理。
  3. 批量应用修饰符:将一些视图组合在一个Group中,可以对这些视图同时应用样式或修饰符。

基本用法

假设我们有一个界面包含多个文本视图,并希望将它们组合在一起,且统一应用相同的样式。Group就是一个非常理想的选择:

import SwiftUIstruct GroupContentView: View {var body: some View {Group {Text("视图 1")Text("视图 2")Text("视图 3")}.font(.title).foregroundColor(.blue)}
}

通过使用Group我们可以在一次性对所有子视图设置字体和颜色,简化了代码。这样无需单独对每个Text视图应用修饰符,而是通过Group一次性实现。

HStack、VStack、ZStack

这三个容器在前面的博客中我们已经介绍过了,在这里就不在重复叙述。

结语

在SwiftUI中,容器组件如NavigationView、TabView、Group等,赋予了开发者更简介、直观的布局和导航方式。相比于UIKit,SwiftUI的声明式编程模式大大简化了代码量,让我们可以更专注于设计直观、流程的用户体验。

  • NavigationView提供了简单的页面层级导航。
  • TabView让多个标签导航实现变得轻松灵活。
  • Group则是轻量的组合工具,在代码组织和样式批量应用上发挥了作用。

这些容器帮助我们快速构建和管理复杂组件,使开发过程更高效。希望通过本文的介绍,大家能够熟悉SwiftUI中的重要容器组件,并能灵活地将它们应用到实际项目中,不断提升界面的美观性和用户体验。

相关文章:

SwiftUI(十二)- 容器组件 布局与结构的基石

引言 在用户界面开发中,布局是设计一个应用程序的视觉层次和交互体验的核心之一。无论是设计简单的按钮排布,还是复杂的多层次页面,合理的布局和结构可以极大地提升用户体验。而容器组件,作为将多个视图整合、组织、排列的工具&a…...

想租用显卡训练自己的网络?AutoDL保姆级使用教程(PyCharm版)

各位小伙伴们大家好~ 不知道各位同学在科研过程中是否有这样的苦恼 电脑无显卡。难不成我要用CPU跑实验吗?救救我吧电脑显卡算力太低。训练过程慢慢慢慢慢,等半天都出不来结果电脑显卡显存不够,batchsize稍微高一点点,就要爆显存…...

LeetCode【0039】组合总和

本文目录 1 中文题目2 求解方法:回溯法2.1 方法思路2.2 Python代码2.3 复杂度分析 3 题目总结 1 中文题目 给定一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#…...

AscendC从入门到精通系列(一)初步感知AscendC

1 什么是AscendC Ascend C是CANN针对算子开发场景推出的编程语言,原生支持C和C标准规范,兼具开发效率和运行性能。基于Ascend C编写的算子程序,通过编译器编译和运行时调度,运行在昇腾AI处理器上。使用Ascend C,开发者…...

PostgreSQL中的COPY命令:高效数据导入与导出

在PostgreSQL数据库中,数据导入和导出是日常工作中常见的操作。传统的插入(INSERT)方法虽然可以实现数据的导入,但在处理大量数据时效率较低。而COPY命令则提供了一个快速、高效的方式来完成这一任务。COPY命令不仅可以用于将数据…...

【HAL库】STM32F105VCTx多通道ADC+DMA方式的【STM32CubeMX】配置及代码实现

相关代码编写 配置好后点击生成代码,在生成代码的adc.c文件中的初始化函数MX_ADC1_Init中添加如下代码: HAL_ADCEx_Calibration_Start(&hadc1); /* 校准ADC */HAL_ADC_Start_DMA(&hadc1,(uint32_t*)ADC_Value,ADC_DMA_…...

[SaaS] 数禾科技 AIGC生成营销素材

https://zhuanlan.zhihu.com/p/923637935https://zhuanlan.zhihu.com/p/923637935...

vue3中查找字典列表中某个元素的值对应的列表索引值

vue3中查找字典列表中某个元素的值对应的列表索引值 目录思路方法代码实现示例解释说明 目录 思路方法 要获取字典列表中某个元素的值对应的列表索引值,可以使用数组的 findIndex 方法。这个方法返回数组中满足提供的测试函数的第一个元素的索引。如果没有找到&am…...

爱普生机器人EPSON RC

爱普生机器人Epson RC系列,搭配其专用的Epson RC编程语言和软件环境,为用户提供了一个直观且功能强大的机器人控制和编程解决方案。以下是对Epson RC及爱普生机器人的一些详细介绍: Epson RC 定义:Epson RC 是爱普生机器人技术中…...

Linux探秘坊-------1.系统核心的低语:基础指令的奥秘解析(1)

1.Linux的背景介绍 Linux 操作系统的发展历程充满了激情与创新喵~🎀 萌芽期 (1983 - 1991):Linux 的历史可追溯到 1983 年,理查德斯托曼 (Richard Stallman) 发起 GNU 计划,目标是创建一个自由软件操作系统。1987 年发…...

❤React-JSX语法认识和使用

1、JSX基本使用​ JSX是React的核心 JSX是ES的扩展 jsx语法 -> 普通的JavaScript代码 -> babel React可以使用JSX的前提和原因: React生态系统支持: 脚手架通常用于构建React应用程序,而JSX是React框架的核心语法之一。因此&#xf…...

51单片机应用开发(进阶)---定时器应用(电子时钟)

实现目标 1、巩固定时器的配置流程; 2、掌握按键、数码管与定时器配合使用; 3、功能1:(1)简单显示时间。显示格式:88-88-88(时-分-秒) 4、功能2:(1&#…...

JavaScript中的对象-栈内存和堆内存以及this指向的两种情况(后续会出进阶)

1.1 栈内存和堆内存 我们知道程序是需要加载到内存中来执行的,我们可以将内存划分为两个区域:栈内存和堆内存 原始类型占据的空间是在栈内存中分配的对象类型占据的空间是在堆内存中分配的 1.1.1 值类型和引用类型 原始类型的保存方式:在变量中保存的是…...

shell脚本使用curl上传FTP

背景:要求使用curl通过shell脚本实现上传文件到FTP的功能,同时对远程目录不存在的时候,主动创建目录并上传文件,shell脚本如下: #!/bin/bash# FTP服务器的地址 FTP_SERVER"ftp://1.1.1.1:2121" # FTP用户名…...

【漏洞分析】Fastjson最新版本RCE漏洞

01漏洞编号 CVE-2022-25845CNVD-2022-40233CNNVD-202206-1037二、Fastjson知多少 万恶之源AutoType Fastjson的主要功能是将Java Bean序列化为JSON字符串,这样得到的字符串就可以通过数据库等方式进行持久化了。 但是,Fastjson在序列化及反序列化的过…...

【项目开发 | 跨域认证】JSON Web Token(JWT)

未经许可,不得转载。 文章目录 JWT设计背景:跨域认证JWT 原理JWT 结构JWT 使用方式注意JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理、结构及用法。 JWT设计背景:跨域认证 互联网服务的用户认证流程是现代应用中的核心组成部分,通常的流程…...

杨中科 .Net Core 笔记 DI 依赖注入2

ServiceCollection services new ServiceCollection();//定义一个承放服务的集合 services.AddScoped<iGetRole, GetRole>();using (ServiceProvider serviceProvider services.BuildServiceProvider()) {var list serviceProvider.GetServices(typeof(iGetRole));//获…...

微信版产品目录如何制作?

微信作为我国最流行的社交媒体平台&#xff0c;拥有庞大的用户群体。许多企业都希望通过微信来推广自己的产品&#xff0c;提高品牌知名度。制作一份精美、实用的微信版产品目录&#xff0c;是企业微信营销的重要手段。微信版产品目录的制作方法&#xff0c;帮助您轻松入门。 ​…...

使用HTML、CSS和JavaScript创建动态圣诞树

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a…...

机器学习-35-提取时间序列信号的特征

文章目录 1 特征提取方法1.1 特征提取过程1.2 两类特征提取方法2 基于数据驱动的方法2.1 领域特定特征提取2.2 基于频率的特征提取2.2.1 模拟信号2.2.2 傅里叶变换2.2.3 抽取最大幅值对应特征2.2.4 抽取峰值幅值对应特征2.3 基于统计的特征提取2.4 基于时间的特征提取3 参考附录…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...