Липкий раздел в SwiftUI scrollview

#swiftui #scrollview

#swiftui #scrollview

Вопрос:

Я пытаюсь смоделировать заголовок липкого раздела, который имеет 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 ZStack with scrollView ) — как только заголовки перекрываются, я просто показываю верхний и скрываю его внутри ScrollView, и на самом деле это выглядит довольно хорошо, так же, как липкий раздел списка.

Мой вопрос: могу ли я каким-то образом повторно использовать один и тот же вид для анимации / перевода / обновления в этих двух местах (inside scrollView -> swipeUp -> static above scrollView -> swipe down -> inside scrollView ), потому что прямо сейчас, если есть какое-либо внутреннее состояние tabHeader , оно не будет работать, потому что это 2 разныхпредставления, поэтому все состояние, которое у них есть, должно быть в их родительском и передаваться как привязка. Если это невозможно, могу ли я каким-то образом ограничить просмотр от наличия внутреннего состояния путем реализации какого-либо протокола или чего-то еще?

введите описание изображения здесь