经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
SwiftUI 简明教程之滑动视图
来源:cnblogs  作者:Bruce2077  时间:2021/6/15 9:09:19  对本文有异议

本文为 Eul 样章,如果您喜欢,请移步 AppStore/Eul 查看更多内容。

Eul 是一款 SwiftUI & Combine 教程 App(iOS、macOS),以文章(文字、图片、代码)配合真机示例(Xcode 12+、iOS 14+,macOS 11+)的形式呈现给读者。笔者意在尽可能使用简洁明了的语言阐述 SwiftUI & Combine 相关的知识,使读者能快速掌握并在 iOS 开发中实践。

List

构建

基础构建方法

List 最基本的构建方法:

  1. List {
  2. Text("Sun")
  3. Text("Cloud")
  4. Text("Snow")
  5. }

数据源

通常我们的列表并非静态,而是与动态的数据源绑定的。List 可以通过传入 data 来实现,不过这里的 data 需要遵循 Identifiable 协议,这样才能保证数据的唯一性。

我们先对天气作如下定义:

  1. struct Weather: Identifiable {
  2. let id = UUID()
  3. let name: String
  4. let icon: String
  5. }

id 是协议要求实现的属性(遵循 Hashable 协议),我们也可以在实例初始化时传入 0, 1, 2, 3...只要是没有冲突的哈希值都可以。这里我们有个简单的处理方法,就是通过 UUID() 生成惟一值,在初始化时可以省去传参。

然后我们添加数据源:

  1. @State private var weathers = [
  2. Weather(name: "Sunshine", icon: "sun.max.fill"),
  3. Weather(name: "Cloud", icon: "cloud"),
  4. Weather(name: "Snow", icon: "snow"),
  5. Weather(name: "Rain", icon: "cloud.rain.fill")
  6. ]

生成 List:

  1. List(weathers) { v in
  2. Label(v.name, systemImage: v.icon)
  3. }

可展开列表

List 可以通过树形结构的数据源直接构建可展开的列表,比如我们定义如下可展开的天气对象:

  1. struct ExpandWeather: Identifiable {
  2. let id = UUID()
  3. var name: String
  4. var icon: String
  5. var weathers: [ExpandWeather]?
  6. }

该结构体内嵌的 weathers 的元素类型就是它本身,而且是可选类型。我们构造如下数据:

  1. let expandWeather: [ExpandWeather] = [
  2. ExpandWeather(name: "Weather", icon: "", weathers: [
  3. ExpandWeather(name: "Sunshine", icon: "sun.max.fill"),
  4. ExpandWeather(name: "Cloud", icon: "cloud"),
  5. ExpandWeather(name: "Snow", icon: "snow"),
  6. ExpandWeather(name: "Rain", icon: "cloud.rain.fill")
  7. ])
  8. ]

然后通过如下方法构建视图:

  1. List(expandWeather, children: \.weathers) { weather in
  2. Label(weather.name, systemImage: weather.icon)
  3. }

最后得到的就是一个可以展开的列表,当然我们可以构造更加复杂的多级展开列表,其原理是一样的,都是在子数据中嵌套更多数据类型相同的子数据。

样式

List 有多种样式,系统为我们提供了多种 ListStyle。其中,iOS 比较常用的除了系统默认样式外,还有 GroupedListStyle 和 InsetGroupedListStyle。

ForEach

基本使用

ForEach 能通过循环从集合数据中快速构建视图。集合数据 data 可以是 Range<Int> 类型,也可以是元素遵循 Identifiable 协议的数组。

比如:

  1. ForEach(0..<2) { idx in
  2. Text("\(idx)")
  3. }

或者,我们仍然以上文的 weathers 作为 data ,

  1. ForEach(weathers) { weather in
  2. Text(weather.name)
  3. }

ForEach 里有个参数 id,它用来保证数据的唯一性。上例中我们并没有显示地调用它,因为对 Range 类型的 data 而言,其 id 默认值就是 Int 元素的值,而 weathers 中的 Weather 实例,我们已经给 id 默认赋值为 UUID() 了,ForEach 会通过 keyPath 取到其中的 id,所以我们也不必显示传参。

如果我们只是想通过一个普通的字符串数组去实现循环创建视图,那么 id 可以显示指定为 \.self,即使用字符串本身作为 id 来保证数据的唯一性。

  1. ForEach(["A", "B"], id: \.self) { str in
  2. Text(str)
  3. }

编辑操作

还记得我们前面提到过得 EditButton 吗?之前我们并没有具体讲解它的用法,现在我们可以见到它的具体使用了。

ForEach 和 List 配合使用,可以轻松地对列表进行编辑操作:delete、move。还是以 weathers 作为数据源,我们构建列表视图:

  1. var body: some View {
  2. List {
  3. ForEach(weathers) { v in
  4. Label(v.name, systemImage: v.icon)
  5. }
  6. .onDelete(perform: onDelete)
  7. .onMove(perform: onMove)
  8. }
  9. .navigationBarItems(trailing: EditButton())
  10. }
  11. func onDelete(offsets: IndexSet) {
  12. weathers.remove(atOffsets: offsets)
  13. }
  14. func onMove(fromOffsets: IndexSet, toOffset: Int) {
  15. weathers.move(fromOffsets: fromOffsets, toOffset: toOffset)
  16. }

EditButton 终于登场了,试试对列表进行编辑操作。

这里的编辑操作只是单选操作,如果我们要多选呢?可以在 List 中绑定 selection 数据,通过它对多条数据同时操作。这里就不举例了,读者可以按照这个思路去实现。

ScrollView

ScrollView 只有一个构建方法:

  1. init(_ axes: Axis.Set = .vertical, showsIndicators: Bool = true, content: () -> Content)

使用也简单,这里不再赘述。

ScrollViewReader

ScrollViewReader 的回调闭包返回的是一个 ScrollViewProxy 实例,它只有一个实例方法 scrollTo(),该 方法能够使 ScrollView 滑动到指定的位置,对 List 也同样适用。

scrollTo() 还可以传入 anchor 参数控制更精确的滑动,比如示例所示为:sr.scrollTo(70, anchor: .center)

如果需要给滑动添加动画效果,只需要在 withAnimation 的闭包中调用 scrollTo() 即可。

本文为 Eul 样章,如果您喜欢,请移步 AppStore/Eul 查看更多内容。

原文链接:http://www.cnblogs.com/bruce2077/p/14859748.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号