简体   繁体   English

在 SwiftUI 中单击按钮上的 NavigationView 和 NavigationLink?

[英]NavigationView and NavigationLink on button click in SwiftUI?

I am trying to push from login view to detail view but not able to make it.even navigation bar is not showing in login view.我正在尝试从登录视图推送到详细信息视图,但无法成功。即使是导航栏也没有显示在登录视图中。 How to push on button click in SwiftUI?如何在 SwiftUI 中点击按钮? How to use NavigationLink on button click?如何在单击按钮时使用 NavigationLink?

var body: some View {
    
    NavigationView {
        VStack(alignment: .leading) {
            Text("Let's get you signed in.")
                .bold()
                .font(.system(size: 40))
                .multilineTextAlignment(.leading)
                .frame(width: 300, height: 100, alignment: .topLeading)
                .padding(Edge.Set.bottom, 50)
            
            Text("Email address:")
                .font(.headline)
            TextField("Email", text: $email)
                .frame(height:44)
                .accentColor(Color.white)
                .background(Color(UIColor.darkGray))
                .cornerRadius(4.0)
            
            Text("Password:")
                .font(.headline)
            
            SecureField("Password", text: $password)
                .frame(height:44)
                .accentColor(Color.white)
                .background(Color(UIColor.darkGray))
                .cornerRadius(4.0)
            
            Button(action: {
                print("login tapped")
            }) {
                HStack {
                    Spacer()
                    Text("Login").foregroundColor(Color.white).bold()
                    Spacer()
                }
            }
            .accentColor(Color.black)
            .padding()
            .background(Color(UIColor.darkGray))
            .cornerRadius(4.0)
            .padding(Edge.Set.vertical, 20)
        }
        .padding(.horizontal,30)
    }
    .navigationBarTitle(Text("Login"))
}

To fix your issue you need to bind and manage tag with NavigationLink , So create one state inside you view as follow, just add above body.要解决您的问题,您需要使用NavigationLink绑定和管理标签,因此在您的视图中创建一个状态,如下所示,只需添加上面的正文。

@State var selection: Int? = nil

Then update your button code as follow to add NavigationLink然后按如下方式更新您的按钮代码以添加NavigationLink

NavigationLink(destination: Text("Test"), tag: 1, selection: $selection) {
    Button(action: {
        print("login tapped")
        self.selection = 1
    }) {
        HStack {
            Spacer()
            Text("Login").foregroundColor(Color.white).bold()
            Spacer()
        }
    }
    .accentColor(Color.black)
    .padding()
    .background(Color(UIColor.darkGray))
    .cornerRadius(4.0)
    .padding(Edge.Set.vertical, 20)
}

Meaning is, when selection and NavigationLink tag value will match then navigation will be occurs. Meaning is, when selection and NavigationLink tag value will match then navigation will be occurs.

I hope this will help you.我希望这能帮到您。

The accepted answer uses NavigationLink(destination:tag:selection:) which is correct.接受的答案使用正确的NavigationLink(destination:tag:selection:)

However, for a simple view with just one NavigationLink you can use a simpler variant: NavigationLink(destination:isActive:)但是,对于只有一个NavigationLink的简单视图,您可以使用更简单的变体: NavigationLink(destination:isActive:)


Usage #1用法 #1

NavigationLink is activated by a standard Button : NavigationLink由标准Button激活:

struct ContentView: View {
    @State var isLinkActive = false

    var body: some View {
        NavigationView {
            VStack(alignment: .leading) {
                ...
                NavigationLink(destination: Text("OtherView"), isActive: $isLinkActive) {
                    Button(action: {
                        self.isLinkActive = true
                    }) {
                        Text("Login")
                    }
                }
            }
            .navigationBarTitle(Text("Login"))
        }
    }
}

Usage #2用法 #2

NavigationLink is hidden and activated by a standard Button : NavigationLink由标准Button隐藏和激活:

struct ContentView: View {
    @State var isLinkActive = false

    var body: some View {
        NavigationView {
            VStack(alignment: .leading) {
                ...
                Button(action: {
                    self.isLinkActive = true
                }) {
                    Text("Login")
                }
            }
            .navigationBarTitle(Text("Login"))
            .background(
                NavigationLink(destination: Text("OtherView"), isActive: $isLinkActive) {
                    EmptyView()
                }
                .hidden()
            )
        }
    }
}

Usage #3用法 #3

NavigationLink is hidden and activated programmatically: NavigationLink以编程方式隐藏和激活:

struct ContentView: View {
    @State var isLinkActive = false

    var body: some View {
        NavigationView {
            VStack(alignment: .leading) {
                ...
            }
            .navigationBarTitle(Text("Login"))
            .background(
                NavigationLink(destination: Text("OtherView"), isActive: $isLinkActive) {
                    EmptyView()
                }
                .hidden()
            )
        }
        .onAppear {
            self.isLinkActive = true
        }
    }
}

Here is a GitHub repository with different SwiftUI extensions that makes navigation easier.这是一个GitHub 存储库,它具有不同的 SwiftUI 扩展,使导航更容易。

Another approach:另一种方法:

SceneDelegate场景委托

if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: BaseView().environmentObject(ViewRouter()))
            self.window = window
            window.makeKeyAndVisible()
        }

BaseView基础视图

import SwiftUI

struct BaseView : View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        VStack {
            if viewRouter.currentPage == "view1" {
                FirstView()
            } else if viewRouter.currentPage == "view2" {
                SecondView()
                    .transition(.scale)
            }
        }
    }
}

#if DEBUG
struct MotherView_Previews : PreviewProvider {
    static var previews: some View {
        BaseView().environmentObject(ViewRouter())
    }
}
#endif

ViewRouter视图路由器

import Foundation
import Combine
import SwiftUI

class ViewRouter: ObservableObject {

    let objectWillChange = PassthroughSubject<ViewRouter,Never>()

    var currentPage: String = "view1" {
        didSet {
            withAnimation() {
                objectWillChange.send(self)
            }
        }
    }
}

FirstView第一视图

import SwiftUI

struct FirstView : View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        VStack {
            Button(action: {self.viewRouter.currentPage = "view2"}) {
                NextButtonContent()
            }
        }
    }
}

#if DEBUG
struct FirstView_Previews : PreviewProvider {
    static var previews: some View {
        FirstView().environmentObject(ViewRouter())
    }
}
#endif

struct NextButtonContent : View {
    var body: some View {
        return Text("Next")
            .foregroundColor(.white)
            .frame(width: 200, height: 50)
            .background(Color.blue)
            .cornerRadius(15)
            .padding(.top, 50)
    }
}

SecondView第二视图

import SwiftUI

struct SecondView : View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        VStack {
            Spacer(minLength: 50.0)
            Button(action: {self.viewRouter.currentPage = "view1"}) {
                BackButtonContent()
            }
        }
    }
}

#if DEBUG
struct SecondView_Previews : PreviewProvider {
    static var previews: some View {
        SecondView().environmentObject(ViewRouter())
    }
}
#endif

struct BackButtonContent : View {
    var body: some View {
        return Text("Back")
            .foregroundColor(.white)
            .frame(width: 200, height: 50)
            .background(Color.blue)
            .cornerRadius(15)
            .padding(.top, 50)
    }
}

Hope this helps!希望这可以帮助!

Simplest and most effective solution is :最简单和最有效的解决方案是:

NavigationLink(destination:ScoresTableView()) {
                    Text("Scores")
                }.navigationBarHidden(true)
                    .frame(width: 90, height: 45, alignment: .center)
                    .foregroundColor(.white)
                    .background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .leading, endPoint: .trailing))
                    .cornerRadius(10)
                    .contentShape(Rectangle())
                    .padding(EdgeInsets(top: 16, leading: UIScreen.main.bounds.size.width - 110 , bottom: 16, trailing: 20))

ScoresTableView is the destination view. ScoresTableView 是目标视图。

I think above answers are nice, but simpler way should be:我认为上面的答案很好,但更简单的方法应该是:

    NavigationLink {
        TargetView()
    } label: {
        Text("Click to go")
    }

In my opinion a cleaner way for iOS 16+ is using a state bool to present the view.在我看来, iOS 16+更简洁的方法是使用 state bool 来呈现视图。

struct ButtonNavigationView: View {
    @State private var isShowingSecondView : Bool = false
    
    var body: some View {
        NavigationStack {
            VStack{
                Button(action:{isShowingSecondView = true} ){
                    Text("Show second view")
                }
            }.navigationDestination(isPresented: $isShowingSecondView) {
                Text("SecondView")
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SwiftUI 使用 NavigationLink 和 NavigationView - SwiftUI using NavigationLink and NavigationView 在 SwiftUI NavigationView 上显示系统后退按钮,之前没有 NavigationLink - Display system back button on SwiftUI NavigationView with no previous NavigationLink iOS SwiftUI - NavigationView NavigationLink:使用自定义按钮关闭视图 - iOS SwiftUI - NavigationView NavigationLink: Close view with custom Button 在没有 NavigationView 的 SwiftUI 中创建 NavigationLink - Creating a NavigationLink in SwiftUI without NavigationView 如何在 SwiftUI 中使用 NavigationView 和 NavigationLink? - How to use NavigationView and NavigationLink in SwiftUI? SwiftUI:NavigationView/NavigationLink:启动并推送目的地? - SwiftUI: NavigationView/NavigationLink: launch with destination pushed? SwiftUI 带导航链接的消失后退按钮 - SwiftUI disappear back button with navigationLink 使用未解决的标识符“ NavigationLink”; 您是说“ NavigationView”吗? -SwiftUI - Use of unresolved identifier 'NavigationLink'; did you mean 'NavigationView'? - SwiftUI SwiftUI NavigationView在ForEach里面List里面用NavigationLink来回跳转 - SwiftUI NavigationView jumps back and forth with NavigationLink in ForEach inside List 如何使用 NavigationLink 检测单击 NavigationView 项的名称 - How to use NavigationLink to detect name of click NavigationView item
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM