Dun*_*ald 5 scrollview swiftui
我正在尝试在 SwiftUI 中创建两个同步ScrollViews,这样在一个中滚动将导致在另一个中进行相同的滚动。
我正在使用ScrollViewOffset底部显示的类来获取滚动视图偏移值,但无法弄清楚如何滚动其他视图。
我似乎能够通过防止在一个视图中滚动并在另一个视图上设置内容位置()来“破解”它 - 有什么方法可以实际将滚动视图内容滚动到某个位置 - 我知道 ScrollViewReader 似乎允许滚动显示内容项,但我似乎找不到任何可以将内容滚动到偏移位置的内容。
使用position()的问题是它实际上并没有改变ScrollViews滚动条的位置——似乎没有ScrollView.scrollContentsTo(point: CGPoint)。
@State private var scrollOffset1: CGPoint = .zero
HStack {
ScrollViewOffset(onOffsetChange: { offset in
scrollOffset1 = offset
print("New ScrollView1 offset: \(offset)")
}, content: {
VStack {
ImageView(filteredImageProvider: self.provider)
.frame(width: imageWidth, height: imageHeight)
}
.frame(width: imageWidth + (geometry.size.width - 20) * 2, height: imageHeight + (geometry.size.height - 20) * 2)
.border(Color.white)
.id(0)
})
ScrollView([]) {
VStack {
ImageView(filteredImageProvider: self.provider, showEdits: false)
.frame(width: imageWidth, height: imageHeight)
}
.frame(width: imageWidth + (geometry.size.width - 20) * 2, height: imageHeight + (geometry.size.height - 20) * 2)
.border(Color.white)
.id(0)
.position(x: scrollOffset1.x, y: scrollOffset1.y + (imageHeight + (geometry.size.height - 20) * 2)/2)
}
}
//
// ScrollViewOffset.swift
// ZoomView
//
//
import Foundation
import SwiftUI
struct ScrollViewOffset<Content: View>: View {
let onOffsetChange: (CGPoint) -> Void
let content: () -> Content
init(
onOffsetChange: @escaping (CGPoint) -> Void,
@ViewBuilder content: @escaping () -> Content
) {
self.onOffsetChange = onOffsetChange
self.content = content
}
var body: some View {
ScrollView([.horizontal, .vertical]) {
offsetReader
content()
.padding(.top, -8)
}
.coordinateSpace(name: "frameLayer")
.onPreferenceChange(ScrollOffsetPreferenceKey.self, perform: onOffsetChange)
}
var offsetReader: some View {
GeometryReader { proxy in
Color.clear
.preference(
key: ScrollOffsetPreferenceKey.self,
value: proxy.frame(in: .named("frameLayer")).origin
)
}
.frame(width: 0, height: 0)
}
}
private struct ScrollOffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGPoint = .zero
static func reduce(value: inout CGPoint, nextValue: () -> CGPoint) {}
}
Run Code Online (Sandbox Code Playgroud)
小智 11
同步滚动视图。
在此示例中,您可以滚动左侧滚动视图,右侧滚动视图将同步到同一位置。在此示例中,右侧的滚动视图被禁用,并且位置仅通过使用偏移量进行同步。
但是使用相同的逻辑和代码,您可以使左右滚动视图在滚动时同步。
import SwiftUI
struct ContentView: View {
@State private var offset = CGFloat.zero
var body: some View {
HStack(alignment: .top) {
// MainScrollView
ScrollView {
VStack {
ForEach(0..<100) { i in
Text("Item \(i)").padding()
}
}
.background( GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self,
value: -$0.frame(in: .named("scroll")).origin.y)
})
.onPreferenceChange(ViewOffsetKey.self) { value in
print("offset >> \(value)")
offset = value
}
}
.coordinateSpace(name: "scroll")
// Synchronised with ScrollView above
ScrollView {
VStack {
ForEach(0..<100) { i in
Text("Item \(i)").padding()
}
}
.offset(y: -offset)
}
.disabled(true)
}
}
}
struct ViewOffsetKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat.zero
static func reduce(value: inout Value, nextValue: () -> Value) {
value += nextValue()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2276 次 |
| 最近记录: |