Form嵌套VStack时ScrollViewReader的scrollTo失效,求保留VStack的方案
解决SwiftUI Form中VStack导致ScrollViewReader.scrollTo失效的问题
失效原因
Form组件底层会为每个直接子视图生成适配表单样式的容器(类似UITableViewCell的封装逻辑),ScrollViewReader的scrollTo方法依赖滚动容器能直接识别到带有对应id的视图。当把带id的Text嵌套在VStack里时,这个id属于VStack的子视图,无法被Form的滚动容器识别到,导致滚动定位失败。而ScrollView没有这种自动封装的容器层,所以不管视图是否嵌套,都能正常识别内部的id。
解决方案
把id直接绑定到作为Form直接子元素的VStack上,让Form的滚动容器能正确捕捉到滚动目标的标识。修改后的代码如下:
import SwiftUI struct FormScrollVStackView: View { @State var useVStack = false var body: some View { VStack(spacing: 16) { Text("Form Scroll VStack").font(.largeTitle) Toggle("Use VStack", isOn: $useVStack).frame(maxWidth: 200) ScrollViewReader { proxy in Form { ForEach(0..<10) { i in if useVStack { VStack { Text("Item #\(i)").frame(height: 44) } .id(i) // 将id绑定到VStack上 } else { Text("Item #\(i)").id(i).frame(height: 44) } } } .overlay(alignment: .top) { HStack { ForEach(0..<10) { i in Button(action: { withAnimation { proxy.scrollTo(i, anchor: .center) } }, label: { Text("#\(i)") }) } } .padding(4) .background { Color.yellow } .border(Color.blue, width: 1) } } } } } #Preview { FormScrollVStackView() }
这样修改后,不管是否启用VStack,点击顶部按钮都能正常触发滚动定位。
内容的提问来源于stack exchange,提问作者Annett Schwarze
相关产品推荐
相关产品推荐

