Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
176 views
in Technique[技术] by (71.8m points)

swift - Moving from one SwiftIUI view to another

I'm new to app development and I'm building an app which requires moving across different views.

At the moment, I'm using a NavigationView/link setup, however this means each time I place a NavigationView inside a different view with a NavigationView, the size of the view gets smaller and I'm left with multiple back buttons.

Is there a way to avoid this (a different way to change views in SwiftUI without using the Navigation system?)

question from:https://stackoverflow.com/questions/65863069/moving-from-one-swiftiui-view-to-another

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should only use one NavigationView within your app. For example, at your Home screen of the app?

The NavigationLink directs your users to a new view that should not have a NavigationView view. Adding two NavigationViews and linking them together will cause the behaviour you're describing by pushing one NavigationView into another shrinking all other views (and themselves) inside.

Try taking all NavigationView components away from all other views except your main/root view.

For example:

struct ROOT_VIEW: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: SECONDVIEW()) {
                    Text("Show Detail View")
                }.navigationBarTitle("ROOT VIEW")
            }
        }
    }
}

Link with second view (all other views):

struct SECOND_VIEW: View {
    var body: some View {
            VStack {
                Text("This is the second view")
                }.navigationBarTitle("ROOT VIEW", display: .inline)
            }
        }
    }

Only adding .navigationBarTitle("ROOT VIEW", display: .inline) to your second view allows a title to appear at the top (with one back button). You can also add buttons inside each title bar with:

.navigationBarItems(leading:
       // FAR LEFT SIDE OF THE TITLE BAR
        HStack {
            Button(action: {// action goes here}) {
                Image(systemName: "plus")
                    .font(.largeTitle)
            }.foregroundColor(.pink)
        }, trailing:
       // FAR RIGHT SIDE OF THE TITLE BAR
        HStack {
            Button(action: { //action goes here}) {
                Image(systemName: "plus")
                    .font(.largeTitle)
            }.foregroundColor(.blue)
        })

Another Option:

You can direct users between your app without using NavigationViews. You can use simple Boolean states.

For example, say you had a root view screen, and there were three buttons on the screen, one for logging in, one for registering and one for restting a password, each with their own views. You would only show one view based on a boolean value:

struct ROOT_VIEW: View {

    @State var showLogin = true // This will be the default view that gets showed as its default to true
    @State var showRegister = false
    @State var showPasswordReset = false


    var body: some View {
        VStack{
            if showLogin{
                LoginView(showLogin: $showLogin, showRegister: $showRegister)
            }
            if showRegister{
                RegisterView()
            }
            if showPasswordReset{
                PasswordResetView()
            }
        }
    }
}


struct LoginView: View {

    @Binding var showLogin: Bool
    @Binding var showRegister: Bool


    var body: some View {
        VStack{
            Button(action: {
                // Change two bool values to switch to register view (turning off login view and turning on reigster view)
                showLogin.toggle()
                showRegister.toggle()
            }) {
                Text("Show Register")
            }.foregroundColor(.pink)
        }
    }
}

You would do this to all views that you want the user to go to (obviously). Say you only wanted the RegisterView to only be able to go to the LoginView and vice versa, you'd only need to provide the RegisterView with the the showLogin and showRegister binding bools in the root view as shown:

RegisterView(showLogin: $showLogin, showRegister: $showRegister)

Make sure in your register view, you don't use a normal @State you use a @Binding to sync all Boolean values across views.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...