首页 > 解决方案 > 在 SwiftUI 中获取列表的滚动方向

问题描述

我在 SwiftUI 视图中有一个列表。在 UIHostingController 中。我想根据列表的滚动方向隐藏或显示 UINavigationBar。这个 UINavigationBar 在 UIHostingController 的 UIkit 中。我尝试添加 DragGesture 但它没有在滚动方向上提供连续更新。

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0 {
            navigationController?.setNavigationBarHidden(true, animated: true)
        } else {
            navigationController?.setNavigationBarHidden(false, animated: true)
        }
    }

基本上,我需要在 SwiftUI 中替换上述代码。

请不要建议 LazyList 或任何与 iOS 14 相关的解决方案,因为我的最低 iOS 目标是 iOS 13。

标签: iosswiftswiftuiswiftui-list

解决方案


您可以创建 ScrollViewReader 观察首选项键的变化。

struct DemoScrollViewOffsetView: View {

  @State private var offset = CGFloat.zero

  var body: some View {
      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) { print("offset >> \($0)") }
      }.coordinateSpace(name: "scroll")
  } } 

struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}

这将读取您的内容偏移量并打印出来。


推荐阅读