View in English

  • Apple 开发者
    • 入门汇总

    探索“入门汇总”

    • 概览
    • 学习
    • Apple Developer Program

    及时了解最新动态

    • 最新动态
    • 开发者你好
    • 平台

    探索“平台”

    • Apple 平台
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store

    精选

    • 设计
    • 分发
    • 游戏
    • 配件
    • 网页
    • Home
    • CarPlay 车载
    • 技术

    探索“技术”

    • 概览
    • Xcode
    • Swift
    • SwiftUI

    精选

    • 辅助功能
    • AI 与机器学习
    • App Intents
    • Apple 智能
    • 游戏
    • 安全性
    • Xcode Cloud
    • 社区

    探索“社区”

    • 概览
    • “与 Apple 会面交流”活动
    • 社区活动
    • 开发者论坛
    • 开源

    精选

    • WWDC
    • Swift Student Challenge
    • 开发者故事
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Centers
    • 文档

    探索“文档”

    • 文档库
    • 技术概述
    • 示例代码
    • 《人机界面指南》
    • 视频

    发布说明

    • 精选更新
    • iPadOS
    • iPadOS
    • macOS
    • watchOS
    • visionos
    • Apple tvOS
    • Xcode
    • 下载

    探索“下载”

    • 所有下载
    • 操作系统
    • 应用程序
    • 设计资源

    精选

    • Xcode
    • TestFlight
    • 字体
    • SF Symbols
    • Icon Composer
    • 支持

    探索“支持”

    • 概览
    • 帮助指南
    • 开发者论坛
    • “反馈助理”
    • 联系我们

    精选

    • 《开发者账户帮助》
    • 《App 审核指南》
    • 《App Store Connect 帮助》
    • 即将实行的要求
    • 协议和准则
    • 系统状态
  • 快速链接

    • 活动
    • 新闻
    • 论坛
    • 示例代码
    • 视频
 

视频

打开菜单 关闭菜单
  • 专题
  • 所有视频
  • 关于
  • 简介
  • 转写文稿
  • SwiftUI 基础知识

    观看在库比提诺现场录制的这个视频,探索重要的 SwiftUI 概念。了解“视图”在不同上下文中的不同含义,以及如何在你的 App 中理解它们。探究内置视图的优势以及如何自定你自己的视图,并了解如何借助依赖关系对代码进行结构化设计,实现与系统的无缝协作。

    这个讲座最初作为“与 Apple 会面交流”活动“SwiftUI 基础知识:使用 SwiftUI 构建卓越的 App”的一部分讲授。请观看完整视频,以了解更多见解和相关讲座。

    资源

      • 高清视频
      • 标清视频
  • 搜索此视频…

    今天,我将分享一些关于 SwiftUI 工作原理的核心概念。

    这些概念将帮助你编写出更好的代码, 同时也会为今天后续的讲解奠定基础。

    首先,我将深入探讨 SwiftUI 视图中一个被频繁使用的术语。

    然后,我将介绍 SwiftUI 内置的视图,

    以及创建新自定义视图背后的逻辑。

    最后,我将讲解依赖关系, 以及如何有目的地组织代码结构。

    在每个部分中,我将分享该部分 最重要的概念,以及它们与编写 优质 SwiftUI 代码 这一大局之间的关联。 好的。

    在 SwiftUI 中,视图(view) 是一个具有多重含义的术语。

    根据上下文的不同,它可以表示三种不同的含义, 这可能会让人有些困惑。

    在许多框架中,视图 指的是用户界面和屏幕上的像素。 在 SwiftUI 中, 视图也是一种协议。

    它是对屏幕上显示内容的描述。 因为每个视图都是一个结构体。

    每个视图的实例 都拥有特定的值。

    这三个概念彼此相关。 屏幕上的像素是视图描述以及该 特定视图结构体实际值的综合结果。

    视图的描述及 其驱动的值共同构成了屏幕上最终显示的像素。

    视图的这三种含义 会在App的不同领域中出现。

    描述即代码本身。

    值则是内存中的实例。 因此, SwiftUI

    可以渲染像素,而屏幕上的像素需要显示最新、 最准确的信息。

    在接下来的演讲中,我将详细探讨视图的这 三种不同含义。

    上下文 非常重要,它将帮助你理清自己

    在 SwiftUI 代码中遇到的问题。

    我将从将视图视为描述这一概念开始讲起。

    在 SwiftUI 中, 视图是具有特定构建方式的描述。

    假设我想展示 一张酷炫的水下场景图片,画面中有人在浮潜。

    为了描述这一点,我会写下短语 underwater snorkeling image。 在 SwiftUI 中, 我通过视图协议来构建这个描述: `Image` 是 SwiftUI 视图, 而 `deep sea` 是图片的名称, 就像我用英语写的短语一样。 视图描述了我想要在 SwiftUI 中实现的内容。

    SwiftUI 会根据视图 决定在屏幕上渲染什么内容。 就像这样。很棒的照片。

    所有 SwiftUI 视图 都是用代码编写的描述。

    无论是内置视图还是你 自己编写的自定义视图,情况都是如此。

    Image 就是 SwiftUI 内置视图的一个例子。

    视图是每个App的构建模块, 而内置视图是入门的绝佳选择。 SwiftUI 中有许多内置视图, 每个视图的名称都描述了它所呈现的内容。

    例如,就像 `Image` 视图用于显示图片一样。

    `Color` 视图会用特定颜色(如紫色) 填充整个画布。

    内置视图之所以强大,是因为 SwiftUI 将其与硬件进行了深度集成。

    这里,这种紫色实际上是一种基于上下文的紫色。

    实际的颜色值会根据设备的上下文进行调整, 例如手机处于浅色模式还是深色模式, 或者屏幕上是否有强烈的阳光照射。

    Text 视图用于显示字符串, 例如Kona Deep Dive。

    与 Color 视图类似, Text 视图也会根据其所在的环境进行优化。

    SwiftUI 会使用适合当前 平台的字体来渲染字符串。 对于 iMac 这样的大屏幕设备, 文本视图的物理尺寸 会比 Apple Watch 等小屏幕设备上的更大。

    文本视图还支持动态类型, 这是一项辅助功能。

    动态类型允许用户 调整设备上可见文本的大小, 以便舒适地阅读。

    在此示例中,右侧手机的系统字体大小较大。

    我 SwiftUI 代码中的文本 视图会自动调整比例, 以确保内容仍可读, 而这无需我编写任何额外代码。

    对于每个视图、图像、颜色和文本, 其名称都是我想要效果的描述,

    结合了深海紫和科纳深潜等具体值。 这些最终会呈现为屏幕上的像素。

    内置视图是一个绝佳的起点, 因为它们不仅开箱即用,还支持自定义。

    自定义视图既能展现App的独特个性, 又能充分利用 SwiftUI 内置视图的优势。

    在 SwiftUI 中, 有多种方法可以自定义视图。 我之前展示的 Text 视图看起来还不错, 但我可以使其更具辨识度。 视图修饰符是用于自定义单个视图的工具。

    接下来我将深入探讨一些代码。 自定义文本

    视图的方法有很多。 例如,更改字体的大小或颜色。 这是我们在愿望清单App 中经常做的事情。 目前,我将从一个简单的方法开始。 我希望我的文本视图 在明亮的背景色上显得格外醒目。

    背景修饰符用于设置视图的背景。 你可以将任何视图作为背景。 我选择了橙色。

    背景就是视图修饰符的一个示例。

    视图修饰符是一种针对特定 视图(如文本视图)调用的方法, 它会返回一个包含原始视图的新视图。

    原始文本视图会被视图修饰符的修改效果包裹, 从而生成一个新视图。

    我喜欢将视图修饰器视为包裹视图的包装器。

    这两行代码共同生成带有橙色背景的原始字符串 Kona Deep Dive。

    这是对原始文本视图的轻微修改版本。 你可以App多个视图修饰 器来创建复合的自定义效果。

    填充(Padding)是另一种视图修饰器。 它会在App的视图边缘添加点。 在此示例中,内边距会 在 Text 视图的四边各增加一点, 随后橙色背景将其填充, 就像背景内边距包裹了 它前面的所有内容一样。 因此,这三行代码在视图层次结构 中代表了一个大型视图。

    关于视图修饰符的最后一点说明: 顺序很重要。 每个视图修饰符仅影响其上方的代码行。

    如果我调换顺序,让背景修饰符排在最前面。 橙色只会覆盖原始的 Text 视图。

    用灰色虚线框标出的内边距则App于其余部分。

    请有意识地安排视图修饰器的顺序。 如果代码的行为与预期不符, 请检查并确认视图的包裹顺序是否合理。

    虽然视图修饰器用于自定义单个视图, 但组合是一种将多个视图结合起来的技术。

    你可以通过组合现有视图来构建自定义视图。

    假设我想在Kona Deep Dive 的愿望 清单搜索标签页中构建这样一行。

    我可以使用之前创建的一些内置视图。

    首先,我将定义我的搜索行视图。

    这是一个结构体,并且符合视图协议。

    然后,我将添加视图的主体。 这是所有视图都必须具备的部分。

    接着,我将添加一张深海的 Image 视图。

    以及一个显示Kona Deep Dive 字样的 Text 视图。 默认情况下, SwiftUI 会将它们垂直堆叠。

    我希望它们并排显示, 因此将添加一个水平堆栈(H 堆栈), 将图片和文本排列在一起。 H 堆栈是一

    种视图,但它不像图像那样描述要渲染什么, 而是描述如何渲染。

    SwiftUI 的 H 堆栈 会将所有子视图(如 图像和文本)以水平线的形式排列。

    今天稍后, Cat 将深入 讲解 SwiftUI 布局的工具和技巧。 即使在制作更复杂的视图时,我也想强调一点。 核心概念是相同的。

    我的搜索行是对所需效果的描述, 而 SwiftUI 会根据该 描述在屏幕上渲染像素。

    组合式设计使代码更易于阅读,

    一旦构建好搜索行, 只需一行代码即可在App的其他区域复用它。

    在我的搜索视图中,无需使用三个堆栈、 三张图片和三个文本视图。 我只需使用三个复合搜索行视图,

    而且后续如果想修改搜索行中的任何内容— —比如将背景改为紫色— —我只需针对该视图进行局部修改即可。

    这不仅减少了需要编写的代码量, 还使代码更易于阅读和理解。

    因为视图本质上是结构体。 它们非常轻量,因此像这样将一个视图 拆分为更小的视图并不会影响性能。

    就像内置视图一样, 自定义视图也是我们对 SwiftUI 应如何在屏幕上 绘制内容的描述。

    诸如 Search 视图 之类的名称固然重要,但更重要的是 `body` 内部的视图及其排列顺序。

    SwiftUI 会根据代码中的描述 在屏幕上绘制像素。现在我想更进一步。 我的搜索行已经非常接近预期设计,但还差一点。

    目前我有三个Kona Deep Dive 的实例,不知道你怎么样, 但我喜欢每年更换度假目的地。 App 是动态的,代表着会发生变化的数据。

    我需要一种方法来切换这些内容, 这样我才能展示愿望清单上的其他旅行。

    这便引出了我的最后一个话题:依赖关系。

    SwiftUI 视图由数据驱动。 无论是数据保持不变的情况—— 比如我的深海图片和字符串 Kona Deep dive, 还是数据发生变化的情况。

    我今天展示的所有视图都依赖于数据。

    屏幕上的像素部分源于图片这样的描述, 部分源于深海这样的数据。

    我之前提到过,所有视图都是结构体, 这意味着所有视图都是值类型, 每个视图实例都有一个值。

    我喜欢这样将视图实例可视化:顶部 是视图名称(如 image), 底部是数据(如 deep sea)。

    SwiftUI 会取一个视图的特定 实例(包括其中的数据), 以此在屏幕上渲染像素。

    一旦像素渲染完成, SwiftUI 就会丢弃该实例。 它不再需要这个实例了。

    这就是视图的第三层含义:视图作为值。

    视图的实例。这些特定的值驱动着屏幕上的像素。

    每个视图实例都只是短暂存在的。 它们寿命很短,仅在需要时才被创建。 它们存在于 SwiftUI 的内存中。 一旦像素渲染完成, 视图的任务就完成了,实例也会被丢弃。

    请注意,丢弃它们并不是一件坏事, 也不会带来什么严重后果。 视图轻量且易于创建。

    我喜欢将视图视为模板, 能够批量生成相同的内容, 从而在屏幕上生成像素。 很多时候,这些模板 代表的数据可以是灵活且动态的。

    例如,在我的App中, 我一直处于深海主题的专注模式, 但同时也需要一张京都的图片。

    这也是一个视图实例, 但它的值略有不同。 图片名称京都与深海不同。

    SwiftUI 会根据图片名称的不同, 将这些具有不同值的 Image 视图 转换为不同的图片。

    现在,我将利用这种灵活性, 重新审视搜索行的代码。

    现在,我的搜索行不再硬编码图片名称和文本, 而是接受图片名称和行程 标题作为参数。

    这个版本的搜索行更加灵活。 我仍然可以用它来制作科纳深潜行, 但也可以用于其他行程。

    这让我更接近

    实际的设计。

    当我在搜索视图中使用新的搜索行时, 我会提供所有不同的图片和行程名称, 比如猛犸红晕和京都神秘。 这样要好得多。

    数据驱动着屏幕上的像素显示, 同时我仍能利用组合式设计带来的简洁代码。

    请注意,这个搜索视图的实现方式仍是对 愿望清单中最终版本的简化。 实际的搜索功能会动态查询数据, 然后根据搜索字段中输入的图片 和字符串来填充搜索行。

    关于这些搜索行,我还想强调一点。

    就像之前的图像视图一样, 每个搜索行的实例都会根据行程名称和照片 名称拥有不同的值。

    SwiftUI 可以轻松比较这些值, 并发现它们并不相等。

    在 SwiftUI 将像素绘制到屏幕上后, 它会释放这些视图的实例。

    因为像素已经渲染完成, 所以不再需要这些视图实例了。

    现在,我想进一步谈谈 SwiftUI 如何处理依赖关系。

    以我的搜索行为例。 描述部分就是我的视图代码。

    视图的不同值会在屏幕上呈现出不同的像素。

    SwiftUI 通过依赖关系来追踪重要值, 这里所说的重要值, 是指那些会根据数据决定像素 显示是否正确的关键值。

    其工作原理如下。

    SwiftUI 首次运行 `body` 时,会通过 一个图来追踪它读取的所有值。

    该图的第一部分是搜索栏的节点。

    在 `body` 中, SwiftUI 读取了图片视图的照片名称值,

    因此它添加了一个照片名称节点, 并添加了一条指向搜索栏的箭头。

    SwiftUI 还读取了行程名称的值, 因此它添加了一个行程名称节点和一条箭头。 SwiftUI 会追踪这两项, 因为要确保像素显示正确,它们必须对应正确的

    照片名称和行程名称。 如果其中任何一项发生变化。 例如,如果我提供一个新的 照片名称(我用这个红点表示), 那么搜索行的像素就会过时, SwiftUI 就需要重新绘制新的像素。

    依赖关系就像视图的输入。

    依赖追踪是 SwiftUI 能够高效 进行更新的原因之一。

    在拥有大量视图和海量数据的App中, 如果每次有某项内容发生变化, SwiftUI 就 必须重新绘制所有内容,那将极其低效。

    App 中的数据变化频繁, 这会导致大量不必要的更新。

    相反, SwiftUI 会追踪依赖关系。

    我在此用箭头来表示, 这些箭头指示哪些视图依赖于特定的数据。

    借助这个系统,当某处发生变化时, SwiftUI 只会重新 计算并重绘下游的内容。

    在App中,事物变化迅速且频繁, 依赖关系追踪确保了 SwiftUI 的高效运行。

    这虽然很复杂,但有个好消息。 你无需自己构建这个图。

    SwiftUI 会通过其 依赖关系图自动为你构建它。

    它会跟踪每个视图在每次

    运行 `body` 时读取的属性。

    该系统能确保依赖关系图始终保持最新状态。 尽管你无需构建或维护这个图, 但在编写代码时,仍有一些事项需要注意。

    在构建视图时,请保持视图轻量级; 考虑你在 `body` 中告知 SwiftUI 需要哪些信息, 以及这些视图的更改是否应导致整个视图失效。

    最好保持视图轻量级且依赖关系尽可能少, 这样 SwiftUI 只会在必要时重绘它们。

    这并不意味着你不能使用复杂的视图。

    这意味着你应该将这些复杂的视图 分解成更小、更简单的部分, 就像我之前在搜索视图中对行所做的那样。

    使用合适的工具来表示你的数据, 并确保仅在需要改变屏幕像素时才传递更改。 视图依赖数据的方式有几种。 一种方式是像我之前那样将数据直接传递给视图, 通过提供图片和行程的具体名称。

    另一种创建数据的方式是 使用 `atState`。

    我的同事 Cole 将在他的演讲 中更深入地探讨 `atState` 以及其他数据流选项, 但我希望先介绍一些基础知识。

    用 `atState` 包裹的属性。 这会告诉 SwiftUI 在视图的整个生命周期内存储该信息。

    即视图位于视图层次结构中的整个生命周期。 我将通过一个简单示例进行演示。

    在愿望清单的搜索标签页中。 当我开始在搜索栏中输入内容时, 结果会实时筛选。

    当我输入字母 J 时, 最前面的项目会被替换为包含 搜索字符串的行程和活动,例如徒步、 约书亚树和悬崖跳水。

    当我再输入一个字母O时, 搜索结果继续筛选。

    在我添加到App中的所有行程和活动中, 约书亚树是唯一包含字符串j o的项目。这就是App的状态。 我输入到搜索字段中的字符串驱动着 搜索结果和屏幕上的显示内容。

    我将构建一个简化的示例来演示 状态是如何工作的。

    这是搜索视图的简化版本, 我将其命名为简单搜索。 它具备真实搜索视图的核心功能, 但在设计上进行了简化。

    主体中只有两个视图。 我使用了一个文本字段 和一个 Text 视图。

    Text 视图只是一个显示 结果在此的占位符。 这是我在原型设计过程中经常采用的做法。 我会先放入占位符,最终会用 一个显示搜索结果的自定义视图替换它。

    文本字段是另一个 SwiftUI 内置视图。 它用于收集用户输入。 当用户点击它时, 键盘会弹出,并显示我输入的字符串。

    我在这里提供了一个起始提示, 然后告诉 SwiftUI 将输入的字符串存储 在名为 Search Value 的变量中。

    `$` 符号是绑定语法, 这是一种数据流工具, Cole 稍后会详细讲解。

    我使用 `@State` 属性包装器对 searchValue 属性进行了装饰。这会告诉 SwiftUI 在更新过程中保留 searchValue 的值。初始值是一个空字符串。 当我点击文本字段时, 光标会闪烁,表示我可以开始输入。

    当我输入字母

    J 时, searchValue的值 便会从空字符串变为J。 SwiftUI 会保留该值, 并据此相应地更新简单搜索的显示效果。

    当我添加字母O 以继续筛选Joshua Tree时, 也会发生同样的情况。

    SwiftUI 会保留 searchValue的值j o, 从而能在多次更新中保持连续的进度。

    `@State` 是建模信息最简单的方式, 这些信息应在视图的整个生命周期内保持不变。

    只要我处于搜索标签页中, 搜索值就会一直保留, 因此我可以继续向其中添加内容。

    如果我离开该标签页,然后稍后返回, 该值将重新从空字符串开始。

    这只是在愿望清单中构 建真实搜索视图的第一步。 接下来,我需要用与搜索值字符串 匹配的行程和活动替换占位符文本视图。

    目前,请专注模式地关注状态的这些方面。

    atState 是 SwiftUI 中的一个属性包装器。

    当一个属性被标记为 atState 时, SwiftUI 会将其视 为App的单一事实来源, 并在更新过程中保留该值。

    状态会在视图的整个生命周期内保存在内存中。

    这意味着App可以显示动态且复合的数据, 例如文本字段中输入的字符串。

    在 SwiftUI 中有多种 方式来构建依赖关系, Cole 稍后会详细介绍每种方式。 目前,我想强调一点: 请花时间了解这些工具的工作原理。 这样,你就能确保自己构建的依赖 关系能够与 SwiftUI 协同工作。

    正如我今天所讲的, 视图是 SwiftUI 的构建模块。 通过更深入地了解它们在不同场景中的 App, 你不仅能理解这个框架, 还能提升代码质量。

    关于今天剩余的演讲内容。 在探索愿望清单的不同领域时, 我建议大家重点关注这些 解决方案背后的理论原理。

    这样,你就能将所学知识应用到自己的App中。

    关于我的演讲内容,请牢记以下几点:

    利用 SwiftUI 的内置 视图来创建自己的自定义视图。 探索不同的修饰符,以展现App的独特之处。

    在构建这些视图或重构现有视图时, 请务必保持视图的轻量级。 仔细考虑每个视图真正需要依赖哪些数据, 并将复杂的视图拆分为更简单、更小的部分。 牢记这些基础原则, 当遇到挑战时,你将更有能力进行分析应对。 非常感谢大家的参与。

开发者页脚

  • 视频
  • Meet with Apple
  • SwiftUI 基础知识
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • AI 与机器学习
    • Apple 智能
    • 音频与视频
    • 增强现实
    • 商务
    • 设计
    • 分发
    • 教育
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 安全性
    • Safari 浏览器与网页
    打开菜单 关闭菜单
    • 文档
    • 下载
    • 示例代码
    • 视频
    • 文档归档
    打开菜单 关闭菜单
    • 帮助指南与文章
    • 联系我们
    • 论坛
    • 反馈与错误报告
    • 系统状态
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件
    • “反馈助理”
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • 安全赏金计划
    • Security Research Device Program
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Academy
    • WWDC
    阅读最近新闻。
    获取 Apple Developer App,并在 bilibili 和微信上关注我们。
    版权所有 © 2026 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则