如何使用ScrollView使图形居中-按像素滚动



我使用ScrollView来显示Graph以水平滚动它。问题是,当视图最初加载时,我需要将其居中。

struct ContentView1: View {
var body: some View {
VStack {
GeometryReader { geometry in
ScrollView(.horizontal) {
VStack {
Graph()
.frame(width: geometry.size.width * 2, height: geometry.size.height, alignment: .center)
}
}
}
}
.frame(minWidth: 400, minHeight: 300, alignment: .center)
}
}

fileprivate struct Graph: View {
var body: some View {
GeometryReader { geometry in
let rect = geometry.size
Path { path in
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: rect.width, y: rect.height))
}
.stroke(Color.black)
Path { path in
path.move(to: CGPoint(x: rect.width, y: 0))
path.addLine(to: CGPoint(x: 0, y: rect.height))
}
.stroke(Color.red)
}
}
}

ScrollViewReader提供了scrollTo函数,但如果ScrollView包含更多具有自己标识符的视图,则该函数有效,因此在这种情况下它不是一个选项。

如何按像素滚动图形以便以编程方式居中?

(我认为(使用ScrollView是不必要的,因为您只有一个View。您可以使用DragGesture在x轴上移动Graph()。它还可以帮助您在Graph()出现时将其居中放置在x-axis上。

1

Graph()偏移屏幕宽度的一半。为此,请定义一个新的@State属性,将其设置为-(geometry.size.width / 2),然后使用.offset()视图修饰符。

2

使用DragGesture()x-axis上移动。您还需要跟踪最后一个偏移。

struct ContentView: View {
@State var offset: CGFloat = .zero
@State var lastOffset: CGFloat = .zero

var body: some View {
VStack {
GeometryReader { geometry in
VStack {
Graph()
.frame(width: geometry.size.width * 2, height: geometry.size.height, alignment: .center)
.offset(x: offset)
}
.onAppear {
offset = -(geometry.size.width / 2)
lastOffset = offset
}
.gesture(
DragGesture().onChanged { value in
offset =  lastOffset + value.translation.width
}
.onEnded { value in
lastOffset = offset
}
)
}
}
.frame(minWidth: 400, minHeight: 300, alignment: .center)
}
}

最新更新