问题描述
当使用 ScrollViewReader 滚动到某个位置时,例如到宽度的 40% - 当 ScrollView 的内容调整大小时,如何保留滚动位置?
我写了一个小示例应用程序来说明问题:
最初,ScrollView 的 child 的宽度为 1600,滚动位置在 40%。当您单击“将宽度更改为 800”按钮时,子宽度将更改为 800,并且 ScrollView 滚动到末尾。 我希望 ScrollView 在调整大小后保留滚动位置,或者在调整大小后始终滚动到 40%。
struct ContentView: View {
@State private var relativeScrollPosition: Double?
@State private var childWidth: CGFloat = 1600
var body: some View {
vstack {
Button("Change width to 800") {
childWidth = 800
}
Button("Change width to 1600") {
childWidth = 1600
}
RelativeScrollView(
relativeScrollPosition: $relativeScrollPosition,childWidth: childWidth
) {
HStack{
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("1")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("2")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("3")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("4")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("5")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("6")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("7")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("8")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("9")
}
ZStack {
Spacer().frame(height: 100).background(Color.green)
Text("10")
}
}
.frame(width: childWidth,height: 100,alignment: .center)
}
.onAppear {
scrollTo40percent()
}
.onChange(of: childWidth,perform: { _ in
scrollTo40percent()
})
}
}
private func scrollTo40percent() {
relativeScrollPosition = 0.4
}
}
struct RelativeScrollView<Content: View>: View {
@Binding var relativeScrollPosition: Double?
let childWidth: CGFloat
let isAnimating = true
var child: () -> Content
var body: some View {
ScrollViewReader { reader in
ScrollView(.horizontal) {
ZStack {
HStack {
// swiftlint:disable identifier_name
ForEach(0..<101) { i in
Spacer().id(i)
}
}
.frame(width: childWidth)
self.child()
}
}
.onAppear {
scroll(reader,to: relativeScrollPosition)
}
.onChange(of: relativeScrollPosition) { newPos in
scroll(reader,to: newPos)
}
}
}
private func scroll(_ reader: ScrollViewProxy,to position: Double?) {
guard let unwrappedPosition = position else { return }
assert(unwrappedPosition >= 0 && unwrappedPosition <= 1)
let elementToScrollTo = Int(unwrappedPosition * 100)
if isAnimating {
withAnimation {
reader.scrollTo(elementToScrollTo,anchor: .center)
}
} else {
reader.scrollTo(elementToScrollTo,anchor: .center)
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)