我尝试使用按钮将 ScrollView 设置为最顶部的元素。因此,新的.scrollPosition()修饰符应该会派上用场。我无法让它工作。在以下示例中,当单击堆栈底部的项目或按钮时,滚动将起作用。但滚动时该值不会更新。您可以通过滚动到底部、单击“滚动到顶部”按钮并向下滚动来重现该行为。第二次,什么也没有发生,因为值仍然是 1。我做错了什么,还是我对修饰符的期望错误?文档是这样说的: https://developer.apple.com/documentation/swiftui/view/scrollposition(id:anchor:)
//\n// ContentView.swift\n// Test\n//\n// Created by Sebastian G\xc3\xb6tte on 23.09.23.\n//\n\nimport SwiftUI\n\nstruct ContentView: View {\n \n @State private var scrollViewPosition: Int?\n \n var body: some View {\n ScrollView(.vertical) {\n VStack(spacing: 32) {\n ForEach(1..<21) { item in\n Text("I am item no. \\(item)")\n .id(item)\n \n .frame(maxWidth: .infinity)\n .padding()\n .background(.purple)\n .cornerRadius(4)\n \n .onTapGesture {\n withAnimation {\n scrollViewPosition = item\n }\n }\n }\n \n Button("Scroll to top", action: {\n withAnimation {\n scrollViewPosition = 1\n }\n })\n }\n .scrollTargetLayout()\n .scrollTargetBehavior(.viewAligned)\n .padding()\n }\n .scrollPosition(id: $scrollViewPosition, anchor: .top)\n \n .onChange(of: scrollViewPosition) { oldValue, newValue in\n print(newValue ?? "No value set")\n }\n }\n}\n\nRun Code Online (Sandbox Code Playgroud)\n
如果您更改VStack为LazyVStack,您的代码就可以工作。
LazyVStack但是,您可能会因某种原因而无法使用。例如,在我的应用程序中,我Layout在ScrollView.
如果您无法使用LazyVStack, ,那么(在我对 iOS 17.0.1 的测试中),使用.id修饰符会阻止 SwiftUI 更新绑定scrollPosition。.id您需要依赖ForEach将 an 分配id给其每个子视图的行为,而不是使用。ForEach这也意味着您需要使用带有参数的版本id:,或者为其提供符合标准的值的集合Identifiable。
因此,为了使您的示例正常工作,请将ForEach循环更改为:
ForEach(1..<21, id: \.self) { item in
Text("I am item no. \(item)")
// .id modifier removed
.frame(maxWidth: .infinity)
.padding()
.background(.purple)
.cornerRadius(4)
.onTapGesture {
withAnimation {
scrollViewPosition = item
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1210 次 |
| 最近记录: |