Search code examples
xcodeswiftuiswiftui-navigationlink

How do I switch between screens in TabView and from the latter to the other View?


I created a simple collection with a button jump to the next View. From the last View there should be a transition to AddItemView, but it doesn't happen - it goes back to the first screen. Can you tell me where I made a mistake? What is the correct way to place the background Image on the first collection screen, so that it won't be on the following screens?

import SwiftUI

struct AddItemView: View {
    var body: some View {
        Text("Hallo!")
    }
}

struct ContentView: View {
    
    var colors: [Color] = [ .orange, .green, .yellow, .pink, .purple ]
    var emojis: [String] = [ "👻", "🐱", "🦊" , "👺", "🎃"]
    @State private var tabSelection = 0
    
    var body: some View {
        
        TabView(selection: $tabSelection) {
            
            ForEach(0..<emojis.endIndex) { index in
                VStack {
                    Text(emojis[index])
                        .font(.system(size: 150))
                        .frame(minWidth: 30, maxWidth: .infinity, minHeight: 0, maxHeight: 250)
                        .background(colors[index])
                        .clipShape(RoundedRectangle(cornerRadius: 30))
                        .padding()
                        .tabItem {
                            Text(emojis[index])
                        }
                    Button(action: {
                        self.tabSelection += 1   
                    }) {
                        if tabSelection == emojis.endIndex {
                            NavigationLink(destination: AddItemView()) {
                                Text("Open View")
                            }
                        } else {
                            Text("Change to next tab")
                        }
                    }
                }
            }
        }
        .tabViewStyle(PageTabViewStyle())
        .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
        .tabViewStyle(PageTabViewStyle.init(indexDisplayMode: .never))
    }
}

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

Solution

  • In this code, you have not to use NavigationView. It's required to navigate to the next screen. Similar concept like Push view controller if navigation controller exists. Also, remove endIndex and use indices.

    struct ContentView: View {
        
        var colors: [Color] = [ .orange, .green, .yellow, .pink, .purple ]
        var emojis: [String] = [ "👻", "🐱", "🦊" , "👺", "🎃"]
        @State private var tabSelection = 0
        
        var body: some View {
            NavigationView { //<- add navigation view
                TabView(selection: $tabSelection) {
                    
                    ForEach(emojis.indices) { index in //<-- use indices
                        VStack {
                            Text(emojis[index])
                                .font(.system(size: 150))
                                .frame(minWidth: 30, maxWidth: .infinity, minHeight: 0, maxHeight: 250)
                                .background(colors[index])
                                .clipShape(RoundedRectangle(cornerRadius: 30))
                                .padding()
                                .tabItem {
                                    Text(emojis[index])
                                }
                            Button(action: {
                                self.tabSelection += 1
                            }) {
                                if tabSelection == emojis.count - 1 { //<- use count
                                    NavigationLink(destination: AddItemView()) {
                                        Text("Open View")
                                    }
                                } else {
                                    Text("Change to next tab")
                                }
                            }
                        }
                    }
                }
                .tabViewStyle(PageTabViewStyle())
                .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
                .tabViewStyle(PageTabViewStyle.init(indexDisplayMode: .never))
            }
        }
    }
    

    If you have already a navigation link from the previous screen then, the problem is you are using endIndex in the wrong way. Check this thread for correct use (https://stackoverflow.com/a/36683863/14733292).