[英]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.