|
1 | | -# 快速上手 <Badge type="warning" text="TODO" /> |
| 1 | +# 快速入门 |
2 | 2 |
|
3 | | -## 学习 SwiftUI <Badge type="warning" text="TODO" /> |
| 3 | +## 学习 Swift |
4 | 4 |
|
5 | | -## Xcode 上手 <Badge type="warning" text="TODO" /> |
| 5 | +Swift 语言是一个苹果开发的现代编程语言。所谓 *现代*,代表它采纳了近些年来一些新出现的观点,比如空值安全、函数式编程等。Swift 语言的设计目标是让开发者更容易编写出安全、高效的代码。同时,Swift 也保持了易上手性,对于有过其他语言编程经验的同学,Swift 语法并不难学。 |
| 6 | + |
| 7 | +想要了解 Swift,可以先从阅读一个 [快速语法概述](https://learnxinyminutes.com/zh-cn/swift/) 开始入手。之后,可以阅读 [官方文档(中文翻译版)](https://gitbook.swiftgg.team/swift)。 |
| 8 | + |
| 9 | +### 学习路线图 |
| 10 | + |
| 11 | +在学习 Swift 语言的过程中,可以特别关注以下内容: |
| 12 | + |
| 13 | +- 基本语法:变量、常量、函数、控制流等 |
| 14 | +- 空值安全:什么是可选类型,以及如何处理它们 |
| 15 | +- 闭包:怎么把函数当成一个变量来对待(SwiftUI 广泛使用闭包) |
| 16 | +- ~~面向对象编程~~ SwiftUI 中不再需要面向对象编程,可以跳过和类继承有关的语法 |
| 17 | +- 并发编程:`async/await` 语法,可以更方便地处理异步任务 |
| 18 | + |
| 19 | +## 学习 SwiftUI |
| 20 | + |
| 21 | +:::tip |
| 22 | +这部分内容可能比较抽象,如果第一次没看懂也不要紧。 |
| 23 | +::: |
| 24 | + |
| 25 | +UI 框架总体来说可以分为两派。 |
| 26 | + |
| 27 | +- 老旧的一派用命令式编程的方式来构建 UI,程序员编写从底层组件一步步构造 UI 的代码。当数据发生变化时,程序员需要手动更新 UI 以反映变化。 |
| 28 | +- 更加新潮的一派用声明式的方式来描述 UI。程序员只声明在不同的数据下他希望看到什么样的 UI,系统会自动将不同的 UI 组件根据声明组合起来,并且在数据变化时自动更新 UI。 |
| 29 | + |
| 30 | +有过前端开发经验的同学可以将直接写 JavaScript 操作 UI 和使用 React、Vue 等框架来描述 UI 进行对比。前者是命令式编程,后者是声明式编程。 |
| 31 | + |
| 32 | +在 iOS 的世界里,命令式编程的代表是 UIKit,声明式编程的代表是 SwiftUI。 |
| 33 | + |
| 34 | +:::warning |
| 35 | +限于篇幅,我们仅对 SwiftUI 做概览性的介绍。之前没有 UI 编程经验的同学可能会觉得下面的内容比较抽象,不要紧,可以先去读一些 SwiftUI 的基础教程再来看。 |
| 36 | +::: |
| 37 | + |
| 38 | +### SwiftUI 编写 UI |
| 39 | + |
| 40 | +SwiftUI 编写 UI 相当直观。使用各种组件并嵌套组合即可。所有组件都是 `View`,`Modifier` 可以修改组件的大小、边距、字体、颜色等。 |
| 41 | + |
| 42 | +```swift |
| 43 | +VStack { |
| 44 | + Text("Hello, world!") |
| 45 | + .padding() |
| 46 | + Image("globe") |
| 47 | + .resizable() |
| 48 | + .aspectRatio(contentMode: .fit) |
| 49 | + .frame(width: 100, height: 100) |
| 50 | +} |
| 51 | +.spacing(20) |
| 52 | +``` |
| 53 | + |
| 54 | +### 响应式 UI 更新 |
| 55 | + |
| 56 | +使用上述方法只能编写一个静态的界面,这个界面本身没有任何状态,和一张图片没有区别。为了让这些 UI 产生变化,我们需要引入 **状态**。 |
| 57 | + |
| 58 | +我们来看一个具体的例子,我们希望在点击按钮时,切换图片的大小。 |
| 59 | + |
| 60 | +```swift |
| 61 | +@State var large = false |
| 62 | + |
| 63 | +VStack { |
| 64 | + if large { |
| 65 | + Button("显示小图") { |
| 66 | + large = false |
| 67 | + } |
| 68 | + } else { |
| 69 | + Button("显示大图") { |
| 70 | + large = true |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + Image("globe") |
| 75 | + .scaleEffect(large ? 2 : 1) |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +可以看到,我们用 `@State` 包装我们的状态 `large`,并且在 `Button` 的点击事件中修改它。SwiftUI 会自动监听这个状态的变化,并且在状态变化时重新渲染 UI。在 UI 代码中,我们可以直接根据不同的状态输出不同的 UI。 |
| 80 | + |
| 81 | +:::details 实现原理 |
| 82 | +`@State` 其实是一个 [属性包装器](https://gitbook.swiftgg.team/swift/swift-jiao-cheng/10_properties#property-wrappers),对 `@State` 包装的变量进行读写时,都要经过这个包装器提供的读写函数。这些函数会在写入新值时通知 SwiftUI 根据新值重新计算 UI。 |
| 83 | +::: |
| 84 | + |
| 85 | +### 跨组件的数据共享 |
| 86 | + |
| 87 | +`State` 很好,但是只能在一个组件内表示状态。在一个大项目中,UI 必须分成很多组件,因此数据必须在不同的组件中传递。在 SwiftUI 中,我们常用以下几种方法来传递数据: |
| 88 | + |
| 89 | +- `Binding` |
| 90 | +- `EnvironmentObject` |
| 91 | +- `ObservedObject` / `StateObject` |
| 92 | + |
| 93 | +它们的具体用法其实很重要,但是我写到这里就想摆烂了,大家还是去看教程吧。 |
| 94 | + |
| 95 | +:::warning |
| 96 | +大家看一些比较新的教程可能会看到 `Bindable`、`Observable` 这些比较新潮的东西。它们很诱人,但是它们只支持 iOS 17 以上的系统,而我们目前仍然打算支持 iOS 16,因此很遗憾,我们用不了这些新潮玩意。为了防止大家精神分裂,最好不要看这些新潮玩意的资料。 |
| 97 | +::: |
| 98 | + |
| 99 | +## Xcode 上手 |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +以上是 Xcode 的主界面。 |
| 104 | + |
| 105 | +按顶栏上的播放键可以直接运行项目(在顶栏上可以配置在什么设备/模拟器上跑项目)。 |
| 106 | + |
| 107 | +边栏上是项目文件目录。最上面蓝色的 DanXi 代表项目文件,里面记录了项目怎么构建和一些元数据。其它的文件结构和真正的文件结构是一样的,基本大部分都是代码文件。下面的 Package Dependencies 不是我们自己的代码,是项目依赖。 |
| 108 | + |
| 109 | +## 开始贡献你的内容 |
| 110 | + |
| 111 | +我们的工作流基于 GitHub 的各项功能,请参阅 [GitHub 工作流](/ops/github) 一节。 |
0 commit comments