Why sidebar menu not work properly with tabview?

Viewed 293

I have a simple SwiftUI application. I am using slide menu with animation, it works properly, but when I add TabView items, slide menu not work. In image1 when click slide menu it is work like image2, but when I add TabView like image3, it is not working. Any idea?

Screenshot:

enter image description here

ContentView:

import SwiftUI

struct ContentView: View {
    @State private var isShowing = false
    
    var body: some View {
        NavigationView {
            ZStack {
                if isShowing {
                    SideMenuView(isShowing: $isShowing)
                }
                HomeView()
                    .cornerRadius(isShowing ? 20 : 10)
                    .offset(x: isShowing ? 300 : 0, y: isShowing ? 44: 0)
                    .scaleEffect(isShowing ? 0.8 : 1)
                    .navigationBarItems(leading: Button(action: {
                        withAnimation(.spring()) {
                            isShowing.toggle()
                        }
                    } , label: {
                        Image(systemName: "list.bullet")
                    }))
                
                TabView {
                    NavigationView {
                        Text("Page One")
                            .navigationBarTitle("Page One")
                    }
                    .tabItem {
                        Image(systemName: "1.circle")
                        Text("Page 1")
                    }
                    NavigationView {
                        Text("Page Two")
                            .navigationBarTitle("Page Two")
                    }
                    .tabItem {
                        Image(systemName: "2.circle")
                        Text("Page 2")
                    }
                    NavigationView {
                        Text("Page Three")
                            .navigationBarTitle("Page Three")
                    }
                    .tabItem {
                        Image(systemName: "3.circle")
                        Text("Page 3")
                    }
                }
                .edgesIgnoringSafeArea(.top)
            }.onAppear {
                isShowing=false
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct HomeView: View {
    var body: some View {
        ZStack {
            Color(.white)
        }
    }
}
2 Answers

I think the problem is that you will have to move your TabBar View. So basically you will need your HomeView inside the TabBar and then move the whole TabBar on @State change like this..:

var body: some View {
    ZStack {
        if isShowing {
            Text("Custom View here")
        }
        
        TabView {
            NavigationView {
                HomeView()
                    .navigationBarItems(leading: Button(action: {
                        withAnimation(.spring()) {
                            isShowing.toggle()
                        }
                    } , label: {
                        Image(systemName: "list.bullet")
                    }))
            }
            .tabItem {
                Image(systemName: "1.circle")
                Text("Page 1")
            }
            NavigationView {
                Text("Page Two")
                    .navigationBarTitle("Page Two")
            }
            .tabItem {
                Image(systemName: "2.circle")
                Text("Page 2")
            }
        }
        .edgesIgnoringSafeArea(.bottom)
        //.cornerRadius(isShowing ? 20 : 0) //<< disabled due to strange effect
        .offset(x: isShowing ? 300 : 0, y: isShowing ? 44: 0)
        .scaleEffect(isShowing ? 0.8 : 1)

    }.onAppear {
        isShowing=false
    }
}

It is definitely not optimal, but I think the only best way to go. However, the animation with the tab bar might be strange with the safe area.

Sliding SideMenu's in TabView are a real pain to implement in a SWIFTUI TabView project. I have spent a lot of time attempting what you are attempting to do and cannot get it to work. What you can do is use your SideMenuView and add a static var to your struct Constants for the TabView constants:

```struct Constants {
       static var settingsTab = 0
      } 
```

then add a SideMenuView to the TabView i.e.

```TabView (selection: $selectedTab) {
        SideMenuView(isShowing: .constant(true))
            .tabItem {
                VStack {
                    Image(systemName: "star.fill")
                    Text("Settings")
                }
            }
            .tag(Constants.settingsTab)

  ```      

This will then display a Settings tab on the Bottom Navigation Bar and when selected will take you to your SideMenuView. FYI, I have focused Grouped this and users like it much better than a slidemenu in a TabView user interface. . TabView with Settings Tab

Related