媒介
本文探讨了如何利用 onScrollGeometryChange 视图修饰符有效地监控和管理滚动位置和多少。通过详细的代码示例息争释,你将学习如何利用这些工具创建动态和相应敏捷的用户界面。
SwiftUI 是一个强大的框架,它简化了在苹果平台上构建用户界面的过程。SwiftUI 中的一个基本组件是 ScrollView,它允许用户通过滚动导航内容。然而,管理滚动位置和理解滚动交互可能是一个挑战。ScrollGeometry 和 onScrollGeometryChange 视图修饰符的引入办理了这些挑战,为开发者提供了更多的控制和对滚动行为的深入了解。
什么是 ScrollPosition
ScrollPosition 是一种类型,允许开发者以编程方式读取或更改滚动位置。固然有效,但当用户利用手势与滚动视图交互时,它显得不够全面。以下是一个展示 ScrollPosition 利用的示例:
- 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 in
- Text(verbatim: index.formatted())
- .id(index)
- }
- }
- .scrollPosition($position)
- .animation(.default, value: position)
- }
- }
复制代码 在这个示例中,我们将滚动视图绑定到一个状态属性。当按下按钮时,滚动视图会将其内容偏移移动到指定点。然而,我们无法读取用户通过手势交互设置的详细内容偏移。
引入 ScrollGeometry
SwiftUI 的新 ScrollGeometry 类型以及 onScrollGeometryChange 视图修饰符提供了一个办理方案。这些工具允许开发者在用户交互期间准确读取内容偏移。
利用 onScrollGeometryChange
让我们探索如何利用 onScrollGeometryChange 视图修饰符与 ScrollGeometry:
- struct ContentView: View {
- @State private var scrollPosition = ScrollPosition(y: 0)
- @State private var offsetY: CGFloat = 0
-
- var body: some View {
- ScrollView {
- ForEach(1..<100, id: \.self) { number in
- Text(verbatim: number.formatted())
- .id(number)
- }
- }
- .scrollPosition($scrollPosition)
- .onScrollGeometryChange(for: CGFloat.self) { geometry in
- geometry.contentOffset.y
- } action: { oldValue, newValue in
- if oldValue != newValue {
- offsetY = newValue
- }
- }
- .onChange(of: offsetY) {
- print(offsetY)
- }
- }
- }
复制代码 onScrollGeometryChange 视图修饰符接受三个参数:
- 类型参数:指定要跟踪的滚动多少类型。在此示例中,我们利用 CGFloat 来跟踪内容偏移的 Y 轴。
- 转换闭包:从 ScrollGeometry 实例中提取所需信息。
- 动作闭包:处置惩罚滚动多少的变革,通过比较旧值和新值,允许我们相应地更新状态属性。
高级滚动多少跟踪
ScrollGeometry 提供了许多有代价的属性,如内容偏移、边界、容器大小、可见矩形、内容插入和内容大小。开发者可以提取单个属性或组合多个属性以获得全面的见解。
以下是一个结合内容大小和可见矩形跟踪的示例:
- struct ContentView: View {
- struct ScrollData: Equatable {
- let size: CGSize
- let visible: CGRect
- }
-
- @State private var scrollPosition = ScrollPosition(y: 0)
- @State private var scrollData = ScrollData(size: .zero, visible: .zero)
-
- var body: some View {
- ScrollView {
- ForEach(1..<100, id: \.self) { number in
- Text(verbatim: number.formatted())
- .id(number)
- }
- }
- .scrollPosition($scrollPosition)
- .onScrollGeometryChange(for: ScrollData.self) { geometry in
- ScrollData(size: geometry.contentSize, visible: geometry.visibleRect)
- } action: { oldValue, newValue in
- if oldValue != newValue {
- scrollData = newValue
- }
- }
- .onChange(of: scrollData) {
- print(scrollData)
- }
- }
- }
复制代码 在这个示例中,我们定义了一个 ScrollData 结构来保存大小和可见矩形属性。在利用 onScrollGeometryChange 视图修饰符时,我们将 ScrollData 作为转换闭包的返回类型,从 ScrollGeometry 实例中提取所有所需的数据。
完备代码示例分析
下面是一个完备的 SwiftUI Demo,其中包含了我们刚刚讨论的 ScrollView、ScrollGeometry 和 onScrollGeometryChange 的利用示例。你可以在 Xcode 中运行这个项目来观察其效果。
完备代码示例
- import SwiftUI
- struct ContentView: View {
- @State private var scrollPosition = ScrollPosition(y: 0)
- @State private var offsetY: CGFloat = 0
-
- var body: some View {
- VStack {
- Text("Scroll Offset: \(offsetY, specifier: "%.2f")")
- .padding()
-
- ScrollView {
- ForEach(1..<100, id: \.self) { number in
- Text(verbatim: number.formatted())
- .padding()
- .frame(maxWidth: .infinity)
- .background(Color(.secondarySystemBackground))
- .cornerRadius(8)
- .padding(.horizontal)
- .id(number)
- }
- }
- .scrollPosition($scrollPosition)
- .onScrollGeometryChange(for: CGFloat.self) { geometry in
- geometry.contentOffset.y
- } action: { oldValue, newValue in
- if oldValue != newValue {
- offsetY = newValue
- }
- }
- .onChange(of: offsetY) {
- print(offsetY)
- }
- }
- }
- }
- struct ScrollData: Equatable {
- let size: CGSize
- let visible: CGRect
- }
- struct AdvancedContentView: View {
- @State private var scrollPosition = ScrollPosition(y: 0)
- @State private var scrollData = ScrollData(size: .zero, visible: .zero)
-
- var body: some View {
- VStack {
- Text("Content Size: \(scrollData.size.width, specifier: "%.2f") x \(scrollData.size.height, specifier: "%.2f")")
- .padding()
- Text("Visible Rect: \(scrollData.visible.origin.x, specifier: "%.2f"), \(scrollData.visible.origin.y, specifier: "%.2f") - \(scrollData.visible.width, specifier: "%.2f") x \(scrollData.visible.height, specifier: "%.2f")")
- .padding()
-
- ScrollView {
- ForEach(1..<100, id: \.self) { number in
- Text(verbatim: number.formatted())
- .padding()
- .frame(maxWidth: .infinity)
- .background(Color(.secondarySystemBackground))
- .cornerRadius(8)
- .padding(.horizontal)
- .id(number)
- }
- }
- .scrollPosition($scrollPosition)
- .onScrollGeometryChange(for: ScrollData.self) { geometry in
- ScrollData(size: geometry.contentSize, visible: geometry.visibleRect)
- } action: { oldValue, newValue in
- if oldValue != newValue {
- scrollData = newValue
- }
- }
- .onChange(of: scrollData) {
- print(scrollData)
- }
- }
- }
- }
- @main
- struct ScrollViewDemoApp: App {
- var body: some Scene {
- WindowGroup {
- TabView {
- ContentView()
- .tabItem {
- Label("Basic", systemImage: "1.square.fill")
- }
-
- AdvancedContentView()
- .tabItem {
- Label("Advanced", systemImage: "2.square.fill")
- }
- }
- }
- }
- }
复制代码 如何运行
- 打开 Xcode 并创建一个新的 SwiftUI 项目。
- 将默认天生的 ContentView.swift 文件更换为上面的完备代码。
- 在 @main 注释下的应用程序入口点中,确保你的主视图是 ScrollViewDemoApp。
- 运行项目。
功能解释
- ContentView: 展示基本的滚动偏移追踪功能,通过 onScrollGeometryChange 视图修饰符追踪 Y 轴的内容偏移。
- AdvancedContentView: 展示更高级的滚动多少追踪功能,追踪内容大小和可见矩形的变革。
- ScrollViewDemoApp: 包含 TabView,方便在基本和高级示例之间切换。
总结
今天,我们探讨了 SwiftUI 中的新 ScrollGeometry 类型和 onScrollGeometryChange 视图修饰符。这些工具为开发者提供了对滚动位置和交互的准确控制和洞察,增强了动态和相应敏捷的用户界面的开发。通过利用这些功能,你可以创建更具吸引力和直观的应用程序。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |