ScrollView 的滚动偏移 中 SwiftUI 如何经常使用

前言

WWDC 24 曾经完结,我选择开局写一些关于 SwiftUI 框架行将推出的新特性的文章。往年,苹果继续填补空白,引入了对滚动位置更细粒度的控制。本周,咱们将学习如何操作和读取滚动偏移。

经常使用 scrollPosition

SwiftUI 框架曾经准许咱们经过视图标识符跟踪和设置滚动视图的位置。这种方法成果不错,但无余以更准确地跟踪用户交互。

struct ContentView: View {@State private var position: Int?var body: some View {ScrollView {LazyVStack {ForEach(0..<100) { index inText(verbatim: index.formatted()).id(index)}}.scrollTargetLayout()}.scrollPosition(id: $position)}}

在上方的代码示例中,咱们经常使用了视图标识符和 scrollPosition 润色符来跟踪和设置滚动视图的位置。虽然这种方法成果不错,但在某些状况下,尤其是须要更准确的用户交互跟踪时,它或许不够用。为了补偿这一无余,SwiftUI 引入了新的 ScrollPosition 类型,使咱们能够经过偏移量、滚动视图的边缘、视图标识符等组合滚动位置。

新的 ScrollPosition 类型

SwiftUI 框架引入了新的 ScrollPosition 类型,使咱们能够经过偏移量、滚动视图的边缘、视图标识符等组合滚动位置。

struct ContentView: View {@State private var position = ScrollPosition(edge: .top)var body: some View {ScrollView {Button("Scroll to bottom") {position.scrollTo(edge: .bottom)}ForEach(1..<100) { index inText(verbatim: index.formatted()).id(index)}Button("Scroll to top") {position.scrollTo(edge: .top)}}.scrollPosition($position)}}

如上例所示,咱们定义了 position 形态属性,并经常使用 scrollPosition 视图润色符将滚动视图与形态属性绑定。咱们还搁置了两个按钮,准许你极速滚动到滚动视图中的第一个或最后一个名目。ScrollPosition 类型提供了许多重载的 scrollTo 函数,使咱们能够处置不同的状况。

为滚动减少动画

经过附加动画视图润色符并传递 ScrollPosition 类型的实例作为 value 参数,咱们可以轻松地为编程滚动减少动画。

struct ContentView: View {@State private var position = ScrollPosition(edge: .top)var body: some View {ScrollView {Button("Scroll to bottom") {position.scrollTo(edge: .bottom)}ForEach(1..<100) { index inText(verbatim: index.formatted()).id(index)}Button("Scroll to top") {position.scrollTo(edge: .top)}}.scrollPosition($position).animation(.default, value: position)}}

滚动到特定名目

咱们减少了另一个按钮来将滚动视图的位置更改为随机名目。咱们依然经常使用 ScrollPosition 类型的 scrollTo 函数,但咱们提供了一个可哈希的标识符。这个选项准许咱们将位置更改为特定名目,经过经常使用 anchor 参数,咱们可以选用所选视图的哪个点应该可见。

struct ContentView: View {@State private var position = ScrollPosition(edge: .top)var body: some View {ScrollView {Button("Scroll somewhere") {let id = (1..<100).randomElement() ?? 0position.scrollTo(id: id, anchor: .center)}ForEach(1..<100) { index inText(verbatim: index.formatted()).id(index)}}.scrollPosition($position).animation(.default, value: position)}}

滚动到特定偏移

最后但雷同关键的是 scrollTo 函数的 point 参数重载,准许咱们传递 CGPoint 实例以将视图滚动到内容的特定点。

struct ContentView: View {@State private var position = ScrollPosition(edge: .top)var body: some View {ScrollView {Button("Scroll to offset") {position.scrollTo(point: CGPoint(x: 0, y: 100))}ForEach(1..<100) { index inText(verbatim: index.formatted()).id(index)}}.scrollPosition($position).animation(.default, value: position)}}

如上例所示,咱们经常使用带有 CGPoint 参数的 scrollTo 函数。它还提供重载,准许咱们仅按 X 或 Y 轴滚动视图。

struct ContentView: View {@State private var position = ScrollPosition(edge: .top)var body: some View {ScrollView {Button("Scroll to offset") {position.scrollTo(y: 100)position.scrollTo(x: 200)}ForEach(1..<100) { index inText(verbatim: index.formatted()).id(index)}}.scrollPosition($position).animation(.default, value: position)}}

读取滚动位置

咱们学习了如何经常使用新的 ScrollPosition 类型操作滚动位置,这也准许咱们读取滚动视图的位置。ScrollPosition 提供了可选的 edge、point 和 viewID 属性,以在你编程滚动时读取值。

每当用户与滚动视图交互时,这些属性将变为 nil。ScrollPosition 类型上的 isPositionedByUser 属性准许咱们了解何时用户手势移动滚动视图内容。

提供一个可以运转示例:

上方是一个可以运转的示例代码,演示如何读取和显示滚动视图的位置。咱们将经常使用一个 Text 视图来显示滚动

import SwiftUIstruct ContentView: View {@State private var position = ScrollPosition(edge: .top)@State private var scrollOffset: CGPoint?var body: some View {VStack {ScrollView {LazyVStack {ForEach(0..<100) { index inText("Item \(index)").id(index).padding().background(Color.yellow).cornerRadius(10).padding(.horizontal)}}.scrollPosition($position).onScrollGeometryChange { geometry inscrollOffset = geometry?.contentBounds.origin}}.animation(.default, value: position)if let offset = scrollOffset {Text("Scroll Offset: x = \(Int(offset.x)), y = \(Int(offset.y))").padding()} else {Text("Scroll Offset: not available").padding()}}.padding()}}

在这个示例中,咱们经常使用了onScrollGeometryChange润色符来读取滚动视图的几何变动。每当滚动视图滚动时,geometry?.contentBounds.origin将提供滚动位置的偏移量。咱们将这个偏移量存储在scrollOffset形态属性中,并在视图底部显示的滚动位置。

总结

在本文中,咱们深化讨论了 SwiftUI 框架中 ScrollView 的新特性,特意是如何经过 ScrollPosition 类型成功更准确的滚动控制。咱们引见了如何经常使用 ScrollPosition 类型启动滚动位置的设置和读取,包含经常使用偏移量、视图标识符等形式启动操作。此外,咱们还展现了如何经过动画和事情处置来增强用户体验。经过这些新配置,开发者可以更灵敏地控制滚动视图的行为,从而创立愈加流利和直观的用户界面。宿愿这些内容对你有所协助。

您可能还会对下面的文章感兴趣: