首页 > 解决方案 > SwiftUI 滚动视图中的粘性部分

问题描述

我正在尝试模拟 PlainListStyle 在 scrollView 场景中具有的粘性部分标题:

struct MyScreen: View {
  @State private var scrollViewOffset: CGFloat = .zero

  @State var headerScrollView: CGRect = .zero
  @State var headerTop: CGRect = .zero

  var body: some View {
    VStack(spacing: 0) {
      HStack {
        Text("Static top content")
          .frame(width: UIScreen.main.bounds.width, height: 50)
          .background(Color.red)

        Spacer()
      }

      ZStack(alignment: .top) {
        scrollable

        tabHeader
          .background(Color.white)
          .opacity(shouldSwap ? 1 : 0)
          .rectReader($headerTop, in: .global)
      }
    }
    .background(Color(hex: "#F7F7F7"))
  }

  var tabHeader: some View {

    Text("My Header")
      .frame(width: UIScreen.main.bounds.width, height: 50)
      .background(Color.blue)
  }

  var topContent: some View {
    Text("My scrollable content")
      .frame(width: UIScreen.main.bounds.width, height: 200)
  }

  var scrollable: some View {
    TrackableScrollView(contentOffset: $scrollViewOffset) {
      VStack {
        VStack {
          topContent

          tabHeader
            .opacity(shouldSwap ? 0 : 1)
            .rectReader($headerScrollView, in: .global)
        }

        HStack() {
          // ... content
        }
      }
    }
  }

  var shouldSwap: Bool {
    return headerTop.origin.y >= headerScrollView.origin.y
  }
}

我试图通过tabHeader在两个地方定义我的视图来实现这一点 - 内部scrollview和顶部scrollView(in ZStackwith scrollView) - 一旦标题重叠,我只显示顶部并从 scrollView 内部隐藏一个,它实际上看起来相当不错,就像列出粘性部分。

我的问题是:我能否以某种方式重用相同的视图在这两个位置(内部scrollView-> swipeUp -> 上面的静态scrollView-> 向下滑动 -> 内部scrollView)进行动画/翻译/更新,因为现在,如果有任何内部状态tabHeader,它不起作用,因为它们是 2 个不同的视图,所以它们拥有的所有状态都必须在它们的父级中并作为绑定传递。如果那不可能,我可以通过实现一些协议或其他东西以某种方式限制视图具有内部状态吗?

在此处输入图像描述

标签: swiftuiscrollview

解决方案


推荐阅读