从一个SwiftUI视图切换到另一个视图

3

我是一个新手开发者,正在构建一个需要在不同视图之间移动的应用程序。

目前,我正在使用NavigationView / link设置,但这意味着每次我将NavigationView放置在具有NavigationView的不同视图中时,视图的大小都会变小,而且我会留下多个返回按钮。

是否有一种避免这种情况的方法(在SwiftUI中改变视图的不同方式而无需使用导航系统?)


你需要发布代码。没有代码,无法明确诊断问题。请查看如何创建最小可重现示例,以便您从问题中获得最多的帮助。 - Yrb
1个回答

3

你的应用中应该只使用一个NavigationView。例如,在应用的主屏幕?

NavigationLink将用户引导到一个新的视图,该视图不应该NavigationView视图。添加两个NavigationView并将它们链接在一起将导致您所描述的行为,即将一个NavigationView推入另一个视图,并使所有其他视图(以及它们自身)缩小。

尝试将所有NavigationView组件从除主/根视图之外的所有其他视图中移除。

例如:

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

链接第二个视图(所有其他视图):

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

只需在第二个视图中添加 .navigationBarTitle("ROOT VIEW", display: .inline),即可在顶部显示一个标题(带有一个返回按钮)。您还可以使用以下方式在每个标题栏中添加按钮:

.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)
        })

另一个选项:

您可以不使用NavigationView,而使用简单的布尔状态来在应用程序之间直接引导用户。

例如,假设您有一个根视图屏幕,并且屏幕上有三个按钮,一个用于登录,一个用于注册,一个用于重置密码,每个按钮都有自己的视图。 基于布尔值,您只会显示一个视图:

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)
        }
    }
}

如果你希望让用户能够访问所有视图,那么你需要在所有视图上进行类似的设置。例如,如果你只想让RegisterView只能访问LoginView,反之亦然,你只需要在根视图中提供RegisterView所需的showLoginshowRegister绑定布尔值,如下所示:

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

确保在注册视图中,你不使用普通的@State,而是使用@Binding来同步所有布尔值在视图之间传递。


谢谢,但我使用导航视图从主屏幕(内容视图)转到登录页面,这很好用。但我还需要从登录页面切换到另一个视图,然后从该视图切换到另一个视图...如果有其他更好的切换视图的方法,那就没问题了。 - Rohith Devanathan
让我为你添加另一个选项,而不使用 NavigationViews。 - Nathan
我尝试在一个新项目中实现这个功能,看起来很不错。但是,在LogInView预览部分的底部,我收到了一个错误提示,说“调用中缺少参数'showLogin'和'showRegister'”。 - Rohith Devanathan
感谢你迄今为止的帮助! - Rohith Devanathan
因为您需要使用默认值(仅显示预览)同时提供预览的值。 - Nathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接