title: How can I prevent my SwiftUI view resizing on scroll
body: <p>I’m hoping someone can point me in the right direction - I have been experimenting with SwiftUI, I’ve created a view somewhat similar to the Twitter Profile UI.</p>
  <p>I seem to have a weird effect when the header collapses.</p>
  <p>There is a ‘sweet spot’ in which the header is collapsed and the tab bar resizes by a small amount before the scroll view contains to scroll under the header.</p>
  <p>You can see in <a href="https://gifyu.com/image/oaz8" rel="nofollow noreferrer">this video</a>.</p>
  <p>I don’t want the tab segment to resize at all, instead it should simply stay in place once the header has collapsed and the scroll view should move freely underneath it.</p>
  <p>I’m sure I am missing something obvious, however some fresh eyes might be just the help I need.</p>
  <p>Any thoughts on this would be much appreciated!</p>
  <pre><code>import SwiftUI
  
  struct ContentView: View {
      
      @State private var safeArea: EdgeInsets = EdgeInsets(.zero)
      @State private var offset: CGFloat = 0
      @State private var tabBarOffset: CGFloat = 0
      
      @State var currentTab = &quot;Tab #1&quot;
      @Namespace var animation
      
      var body: some View {
          GeometryReader { foo in
              ScrollView {
                  VStack(spacing: 0) {
                      // Header
                      GeometryReader { proxy -&gt; AnyView in
                          // Sticky Header
                          DispatchQueue.main.async {
                              offset = proxy.frame(in: .global).minY
                              safeArea = foo.safeAreaInsets
                          }
                          
                          return AnyView(makeHeader())
                      }
                      .frame(height: 180)
                      .zIndex(1)
                      
                      // Profile
                      VStack(spacing: 0) {
                          VStack(spacing: 0) {
                              HStack(spacing: 0) {
                                  TabButton(title: &quot;Tab #1&quot;, currentTab: $currentTab, animation: animation)
                                      .frame(maxWidth: .infinity)
                                  TabButton(title: &quot;Tab #2&quot;, currentTab: $currentTab, animation: animation)
                                      .frame(maxWidth: .infinity)
                                  TabButton(title: &quot;Tab #3&quot;, currentTab: $currentTab, animation: animation)
                                      .frame(maxWidth: .infinity)
                              }
                              Divider()
                          }
                          .padding(.top, 20)
                          .background(Color.white)
                          .offset(y: tabBarOffset &lt; 90 ? -tabBarOffset + 90 : 0)
                          .overlay(
                              GeometryReader { proxy -&gt; Color in
                                  DispatchQueue.main.async {
                                      tabBarOffset = proxy.frame(in: .global).minY
                                  }
                                  return Color.clear
                              }
                              .frame(width: 0, height: 0),
                              alignment: .top
                          )
                          .zIndex(1)
                          VStack {
                              ForEach((0..&lt;50)) {
                                  Text(&quot;Row #\($0)&quot;)
                                  Divider()
                              }
                          }
                          .padding(.top)
                          .zIndex(0)
                      }
                  }
              }
              .ignoresSafeArea(.all, edges: .top)
          }
      }
      
      @ViewBuilder func makeHeader() -&gt; some View {
          ZStack {
              // Cover
              Color.gray
                  .frame(maxWidth: .infinity)
                  .frame(height: offset &gt; 0 ? 180 + offset : 180)
          }
          .clipped()
          // Stretchy Effect
          .frame(height: offset &gt; 0 ? 180 + offset : nil)
          .offset(y: offset &gt; 0 ? -offset : -offset &lt; 80 ? 0 : -offset - 80)
      }
  }
  
  struct ContentView_Previews: PreviewProvider {
      static var previews: some View {
          ContentView()
      }
  }
  
  struct TabButton: View {
      var title: String
      @Binding var currentTab: String
      var animation: Namespace.ID
      
      var body: some View {
          Button(
              action: {
                  withAnimation { currentTab = title }
              },
              label: {
                  LazyVStack(spacing: 12) {
                      Text(title)
                          .fontWeight(.semibold)
                          .foregroundColor(currentTab == title ? .blue : .gray)
                          .padding(.horizontal)
                      
                      if currentTab == title {
                          Capsule()
                              .fill(Color.blue)
                              .frame(height: 1.2)
                              .matchedGeometryEffect(id: &quot;TAB&quot;, in: animation)
                      } else {
                          Capsule()
                              .fill(Color.clear)
                              .frame(height: 1.2)
                      }
                      
                  }
              }
          )
      }
  }
  </code></pre>