Ios 加载视图时滚动至scrollview中的选定位置-SwiftUI
大纲 我有两个视图,第一个(视图1)包含一个Ios 加载视图时滚动至scrollview中的选定位置-SwiftUI,ios,swiftui,Ios,Swiftui,大纲 我有两个视图,第一个(视图1)包含一个HStack和一个@observeObject。当用户从HStack中选择一行时,@observateObject将更新为所选行的字符串名称 在视图2中,我的HStack与视图1中的第一个HStack相同。此HStack观察@observegeobject并对除与@observegeobject匹配的行之外的所有其他行进行去饱和 问题 view2中的HStack列表比页面宽,因此我希望在视图出现时自动滚动到饱和/选定行。我不完全确定如何使用Scroll
HStack
和一个@observeObject
。当用户从HStack
中选择一行时,@observateObject
将更新为所选行的字符串名称
在视图2中,我的HStack
与视图1中的第一个HStack
相同。此HStack
观察@observegeobject
并对除与@observegeobject
匹配的行之外的所有其他行进行去饱和
问题
view2中的HStack
列表比页面宽,因此我希望在视图出现时自动滚动到饱和/选定行。我不完全确定如何使用ScrollTo
,因为它需要一个整数,我只存储/观察字符串名
视图1
class selectedApplication: ObservableObject {
@Published var selectedApplication = "application1"
}
struct view1: View {
@ObservedObject var selectedOption = selectedApplication()
var applications = ["application1", "application2", "application3", "application4", "application5", "application6", "application7", "application8", "application9", "application10"]
var body: some View {
VStack{
ScrollView(.horizontal){
HStack{
ForEach(applications, id: \.self) { item in
Button(action: {
self.selectedOption.selectedApplication = item
}) {
VStack(alignment: .center){
Text(item)
}
}
}
}
}
}
}
}
视图2:
struct View2: View {
@ObservedObject var application: selectedApplication
var applications = ["application1", "application2", "application3", "application4", "application5", "application6", "application7", "application8", "application9", "application10"]
var body: some View {
HStack{
ScrollView(.horizontal, showsIndicators: false) {
ScrollViewReader{ scroll in
HStack{
ForEach(applications, id: \.self) { item in
Button(action: {
application.selectedApplication = item
}) {
Text(item)
.saturation(application.selectedApplication == item ? 1.0 : 0.05)
}
}
}
}
}
}
}
}
您可以将
ScrollViewReader
与ForEach
中应用的id
一起使用,这样您实际上就不需要行索引号(尽管如果需要,也可以通过使用枚举的或搜索应用程序
数组来获取该项的索引
以下是我的更新代码:
struct ContentView : View {
@ObservedObject var selectedOption = SelectedApplicationState()
var body: some View {
VStack {
View1(application: selectedOption)
View2(application: selectedOption)
}
}
}
class SelectedApplicationState: ObservableObject {
@Published var selectedApplication = "application1"
var applications = ["application1", "application2", "application3", "application4", "application5", "application6", "application7", "application8", "application9", "application10"]
}
struct View1: View {
@ObservedObject var application: SelectedApplicationState
var body: some View {
VStack{
ScrollView(.horizontal){
HStack{
ForEach(application.applications, id: \.self) { item in
Button(action: {
self.application.selectedApplication = item
}) {
VStack(alignment: .center){
Text(item)
}
}
}
}
}
}
}
}
struct View2: View {
@ObservedObject var application: SelectedApplicationState
var body: some View {
HStack{
ScrollView(.horizontal, showsIndicators: false) {
ScrollViewReader{ scroll in
HStack{
ForEach(application.applications, id: \.self) { item in
Button(action: {
application.selectedApplication = item
}) {
Text(item)
.saturation(application.selectedApplication == item ? 1.0 : 0.05)
}
}
}.onReceive(application.$selectedApplication) { (app) in
withAnimation {
scroll.scrollTo(app, anchor: .leading)
}
}
}
}
}
}
}
工作原理:
我只是制作了一个基本的ContentView来显示这两个视图,因为我不确定它们是如何为您布局的
ContentView拥有SelectedApplicationState
(这是您的selectionApplication
observeObject(顺便说一句,通常的做法是将您的类型名称大写——这就是我更改名称的原因。另外,如果类型和该类型的属性具有如此相似的名称,会让人感到困惑)并将其传递给两个视图
SelectedApplicationState
现在保存applications
数组,因为它在视图中被复制
在View1中选择时,设置ObserveObject中的selectedApplication
,触发View2中的onReceive
在那里,ScrollViewReader
被告知滚动到id存储在selectedApplication
中的项目,该id作为app
传递给onReceive
闭包
如果这些视图位于单独的页面上,那么一旦导航到View2,它的位置仍然会被正确设置,因为onReceive
将在第一次加载时启动并将其设置到正确的位置。唯一的要求是将SelectedApplicationState
的实例传递给用户。这是否回答了您的问题打开?大致说来,谢谢!我确实查看了ScrollViewReader
,并认为我只需要存储行号,然后使用scrollTo
。但是,我不知道如何选择行整数,以便在加载视图时可以使用scrollTo
。这正是我试图实现的。非常感谢您的帮助详细的解释。