是否可以在 SwiftUI 中设置 ScrollView 偏移量?
我制作了一个自定义选项卡栏,它使用 Switch/Case 来更改视图。然而,我的视图都包含垂直滚动视图。我知道每次我在视图之间切换时,它们都会被破坏,因此滚动视图偏移量就会丢失。
我已使用以下方法来获取 ScrollView Offset,但是我现在不确定如何使用此信息。我已经看到现在有 ScrollTo 但这似乎只适用于 ID。
是否可以以某种方式将 ScrollTo 与 Offset 一起使用?
一般来说,我想要实现的是标准选项卡栏行为,其中用户返回到他们离开每个选项卡的相同位置
如有任何帮助,我们将不胜感激。另外,请告诉我这是否对性能不利,因为我是新手。谢谢。
private struct ScrollViewOffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGPoint = .zero
static func reduce(value: inout CGPoint, nextValue: () -> CGPoint) { }
}
struct ScrollViewWithOffset<T: View>: View {
let axes: Axis.Set
let showsIndicator: Bool
let offsetChanged: (CGPoint) -> Void
let content: T
init(axes: Axis.Set = .vertical,
showsIndicator: Bool = false,
offsetChanged: @escaping (CGPoint) -> Void = { _ in },
@ViewBuilder content: () -> T
) {
self.axes = axes
self.showsIndicator = showsIndicator
self.offsetChanged = offsetChanged
self.content = content()
}
var body: some View {
ScrollView(axes, showsIndicators: showsIndicator) {
GeometryReader { proxy in
Color.clear.preference(
key: ScrollViewOffsetPreferenceKey.self,
value: proxy.frame(in: .named("scrollView")).origin
)
}
.frame(width: 0, height: 0)
content
}
.coordinateSpace(name: "scrollView")
.onPreferenceChange(ScrollViewOffsetPreferenceKey.self, perform: offsetChanged)
}
}
像这样使用...
ScrollViewWithOffset { point in
scrollViewOffset = point.y
} content: {
ScrollViewReader { proxy in
LazyVStack(spacing: 4) {
ForEach(0..<10, id: \.self) { i in
Item()
.id(i)
}
}
}
}
ScrollPosition
。
如果您的目标是 iOS 17 及更早版本,您可以使用 HStack 的偏移量或使用 Daniel Saidi 的想法,它使用 GeometryReader。