SwiftUI tabview(滚动)事件?

问题描述 投票:0回答:2

是否可以将滚动更改事件附加到 SwiftUI 中的 TabView? 我想在用户触摸并拖动其中一个视图时获取滚动位置,该位置会在每次位置更改时更新。

    TabView {

        Text("Example 1")
        Text("Example 2")
        Text("Example 3")

    }
    .tabViewStyle(PageTabViewStyle())

我尝试添加 DragGesture,但 TabView 不再工作(可能是因为 DragGesture 接管了输入)。我也没有在 Apple 的文档中看到任何相应的事件。

有谁知道实现这个的方法吗?

干杯..

swiftui scrollview tabview
2个回答
3
投票

我们可以用不同的方式跟踪它——通过改变视图坐标(实际上它几乎与拖动平移相同)

这里是一个标签的圆顶。使用 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)")
    }
}


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
    }
}

}

© www.soinside.com 2019 - 2024. All rights reserved.