title: SwiftUI Navigation similar to Slack
body: <p>I am trying to make a navigation UI similar to the Slack app where I have the Home Screen which Overlays the Menu Navigation screen. I created a ViewModifier which makes the Home Screen Draggable. Now I need to add functionality such that when the "Home" is tapped on the blue Menu screen, the white Home View animates back to the center. My idea was to keep track of the NavigationState in a global AppState:</p>
  
  <pre><code>enum NavigationSelection {
    case menu
    case home
  }
  
  final class AppState: ObservableObject {
    let objectWillChange = PassthroughSubject&lt;Void, Never&gt;()
    @Published var currentNavigationSelection: NavigationSelection = .home 
  }
  </code></pre>
  
  <p>Then when the user taps "Home", have it update the AppState's currentNavigationSelection, and have the Draggable view determine its offset based on the currentNavigationSelection. I'm really not sure about this approach and I'm having a tough time thinking about it in the new SwiftUI style. Any suggestions would be much appreciated.</p>
  
  <p><a href="https://i.stack.imgur.com/XALx1.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XALx1.png" alt="enter image description here"></a></p>
  
  <p>The view hierarchy looks like this:</p>
  
  <pre><code> var body: some View {
      ZStack {
          Menu()
          HomeTabView()
      }
  }
  </code></pre>
  
  <p>And the HomeTabView has a draggable ViewModifier applied: </p>
  
  <pre><code>struct Slidable: ViewModifier {
  
    @EnvironmentObject var app: AppState
  
    @State private var viewState = SlidableViewDragState.normal.defaultPosition
    @State private var currentPosition: SlidableViewDragState = .normal {
      didSet {
          self.viewState = self.currentPosition.defaultPosition
      }
    }
  
    func body(content: Content) -&gt; some View {
      return content
          .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight:
          .infinity, alignment: Alignment.topLeading)
          .offset(self.viewState)
          .animation(.interactiveSpring())
      .gesture(
          DragGesture()
              .onChanged({ (value) in
                  self.viewState = self.currentPosition.applyXTranslation(x: value.translation.width)
              })
              .onEnded({ (value) in
                  if value.translation.width &lt; 0 &amp;&amp; self.currentPosition == .normal {
                      return
                  }
                  if abs(value.translation.width) &gt; self.currentPosition.switchThreshold {
                      self.currentPosition = self.currentPosition.oppositePosition
                      if self.currentPosition == .menuVisible {
                          self.app.currentNavigationSelection = .menu
                      }
                  } else {
                      self.viewState = self.currentPosition.defaultPosition
                  }
              })
      )
    }
  }
  </code></pre>