欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SwiftUI 简明教程之滑动视图

程序员文章站 2022-03-12 22:05:00
本文为 Eul 样章,如果您喜欢,请移步 AppStore/Eul 查看更多内容。 Eul 是一款 SwiftUI & Combine 教程 App(iOS、macOS),以文章(文字、图片、代码)配合真机示例(Xcode 12+、iOS 14+,macOS 11+)的形式呈现给读者。笔者意在尽可能 ......

SwiftUI 简明教程之滑动视图

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

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

list

构建

基础构建方法

list 最基本的构建方法:

list {
  text("sun")
  text("cloud")
  text("snow")
}

数据源

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

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

struct weather: identifiable {
  let id = uuid()
  let name: string
  let icon: string
}

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

然后我们添加数据源:

@state private var weathers = [
  weather(name: "sunshine", icon: "sun.max.fill"),
  weather(name: "cloud", icon: "cloud"),
  weather(name: "snow", icon: "snow"),
  weather(name: "rain", icon: "cloud.rain.fill")
]

生成 list:

list(weathers) { v in
  label(v.name, systemimage: v.icon)
}

SwiftUI 简明教程之滑动视图

可展开列表

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

struct expandweather: identifiable {
  let id = uuid()
  var name: string
  var icon: string
  var weathers: [expandweather]?
}

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

let expandweather: [expandweather] = [
  expandweather(name: "weather", icon: "", weathers: [
    expandweather(name: "sunshine", icon: "sun.max.fill"),
    expandweather(name: "cloud", icon: "cloud"),
    expandweather(name: "snow", icon: "snow"),
    expandweather(name: "rain", icon: "cloud.rain.fill")
  ])
]

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

list(expandweather, children: \.weathers) { weather in
  label(weather.name, systemimage: weather.icon)
}

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

样式

list 有多种样式,系统为我们提供了多种 liststyle。其中,ios 比较常用的除了系统默认样式外,还有 groupedliststyle 和 insetgroupedliststyle。
SwiftUI 简明教程之滑动视图

foreach

基本使用

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

比如:

foreach(0..<2) { idx in
  text("\(idx)")
}

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

foreach(weathers) { weather in
  text(weather.name)
}

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

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

foreach(["a", "b"], id: \.self) { str in
  text(str)
}

SwiftUI 简明教程之滑动视图

编辑操作

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

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

var body: some view {
  list {
    foreach(weathers) { v in
      label(v.name, systemimage: v.icon)
    }
    .ondelete(perform: ondelete)
    .onmove(perform: onmove)
  }
  .navigationbaritems(trailing: editbutton())
}

func ondelete(offsets: indexset) {
  weathers.remove(atoffsets: offsets)
}

func onmove(fromoffsets: indexset, tooffset: int) {
  weathers.move(fromoffsets: fromoffsets, tooffset: tooffset)
}

SwiftUI 简明教程之滑动视图

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

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

scrollview

scrollview 只有一个构建方法:

init(_ axes: axis.set = .vertical, showsindicators: bool = true, content: () -> content)

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

scrollviewreader

scrollviewreader 的回调闭包返回的是一个 scrollviewproxy 实例,它只有一个实例方法 scrollto(),该 方法能够使 scrollview 滑动到指定的位置,对 list 也同样适用。

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

SwiftUI 简明教程之滑动视图

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

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