我使用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)
}
}