是否可以将滚动更改事件附加到 SwiftUI 中的 TabView? 我想在用户触摸并拖动其中一个视图时获取滚动位置,该位置会在每次位置更改时更新。
TabView {
Text("Example 1")
Text("Example 2")
Text("Example 3")
}
.tabViewStyle(PageTabViewStyle())
我尝试添加 DragGesture,但 TabView 不再工作(可能是因为 DragGesture 接管了输入)。我也没有在 Apple 的文档中看到任何相应的事件。
有谁知道实现这个的方法吗?
干杯..
我们可以用不同的方式跟踪它——通过改变视图坐标(实际上它几乎与拖动平移相同)
这里是一个标签的圆顶。使用 Xcode 13.4 / iOS 15.5 测试
var body: some View {
TabView {
Text("Example 1")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(GeometryReader {
// read and store origin (min X) of page
Color.clear.preference(key: ViewOffsetKey.self,
value: $0.frame(in: .global).minX)
})
Text("Example 2")
Text("Example 3")
}
.tabViewStyle(PageTabViewStyle())
.onPreferenceChange(ViewOffsetKey.self) {
// process here update of page origin as needed
print("Offset >> \($0)")
}
}
您可以使用几何阅读器跟踪滑动进度并进行相应处理。下面的这个例子给出了你的问题的解决方案。它会向您显示 Text() 中正确选择的点击页面...
结构内容视图:查看{
enum SwipeDirection {
case left
case right
case none
}
@State var items = [0, 1, 2]
@State var selection: Int = 0
@State var swipeDirection: SwipeDirection = .none
var body: some View {
VStack() {
TabView(selection: $selection) {
ForEach($items.indices, id: \.self) { item in
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world! \(item)")
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.tag(item)
.background(
GeometryReader { proxy in
Color.blue.preference(key: CustomPreferenceKey.self, value: proxy.frame(in: .global).minX)
}
)
}
}.tabViewStyle(.page)
Text("\(selection)")
}
.onPreferenceChange(CustomPreferenceKey.self) {
if $0 >= (UIScreen.main.bounds.width - 20) {
swipeDirection = .left
} else if $0 <= -(UIScreen.main.bounds.width - 20) {
swipeDirection = .right
}
switch swipeDirection {
case .right:
if $0 == 0 {
selection += 1
}
case .left:
if $0 == 0 {
selection -= 1
}
case .none: break
}
swipeDirection = .none
}
}
}