68

我有一个使用 SwiftUI 的按钮的基本视图,我试图在点击按钮时呈现一个新的屏幕/视图。我该怎么做呢?我是否想为这个视图创建一个委托来告诉应用程序SceneDelegate呈现一个新的视图控制器?

import SwiftUI

struct ContentView : View {
    var body: some View {
        VStack {
            Text("Hello World")
            Button(action: {
                //go to another view
            }) {
                Text("Do Something")
                    .font(.largeTitle)
                    .fontWeight(.ultraLight)
            }
        }
    }
}
4

12 回答 12

61

这不是这里的最佳答案 - 如果您不想要导航栏,它是一种替代方法。请参阅下面Jake 的回答NavigationView,了解使用&执行此操作的正常方法NavigationLink。希望这仍然有用或为您指明正确的方向。

如果您只是想NavigationLink使用 a Binding,您可以使用与绑定参数相同的NavigationLinkinit 。isActive

无论如何,回到答案......</sup>


我为此做了一个视图修饰符。这也意味着没有导航栏。你可以这样称呼它:

.navigate(to: MainPageView(), when: $willMoveToNextScreen)

这可以附加到任何东西上,所以我通常将它附加到身体的末端,例如:

@State private var willMoveToNextScreen = false

var body: some View {
    VStack {
        /* ... */
    }
    .navigate(to: MainPageView(), when: $willMoveToNextScreen)
}

代码(记住import SwiftUI):

extension View {
    /// Navigate to a new view.
    /// - Parameters:
    ///   - view: View to navigate to.
    ///   - binding: Only navigates when this condition is `true`.
    func navigate<NewView: View>(to view: NewView, when binding: Binding<Bool>) -> some View {
        NavigationView {
            ZStack {
                self
                    .navigationBarTitle("")
                    .navigationBarHidden(true)

                NavigationLink(
                    destination: view
                        .navigationBarTitle("")
                        .navigationBarHidden(true),
                    isActive: binding
                ) {
                    EmptyView()
                }
            }
        }
        .navigationViewStyle(.stack)
    }
}
于 2020-01-04T16:34:35.387 回答
56

关键是使用 NavigationView 和 NavigationLink:

import SwiftUI

struct ContentView : View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello World")
                NavigationLink(destination: DetailView()) {
                    Text("Do Something")
                }
            }
        }
    }
}
于 2019-06-04T04:47:39.020 回答
8

这是在不使用 NavigationView 的情况下呈现视图的另一种方法。这就像 UIKit 的UIModalPresentationStyle.currentContext.

struct PresenterButtonView: View {
var body: some View {
    PresentationButton(Text("Tap to present"),
                       destination: Text("Hello world"))
}}
于 2019-06-05T02:47:59.630 回答
8

如果不想显示导航视图,可以将其隐藏在目的地。

struct ContentViewA : View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello World")
                NavigationLink(destination: ContentViewB()) {
                    Text("Go To Next Step")
                }
            }
        }
    }
}



struct ContentViewB : View {
        var body: some View {
            NavigationView {
                VStack {
                    Text("Hello World B")

                }.navigationBarTitle("")
                .navigationBarHidden(true)
            }
        }
    }

或者,如果您想根据可@State用于更改可见性的条件隐藏它。

于 2020-06-07T10:53:08.383 回答
4

现在我们可以使用NavigationLink


档案一:

struct ContentView: View {
var body: some View {
    NavigationView {
        VStack {
            Text("Hello World")
            NavigationLink(destination: secondView()) {
                Text("Hit Me!")
                    .fontWeight(.semibold)
                    .font(.title)
                    .padding()
                    .foregroundColor(.white)
                    .background(LinearGradient(gradient: Gradient(colors: [Color(.white),Color(.blue)]), startPoint: .leading, endPoint: .trailing))
                    .cornerRadius(40)
        }
      }
    }
  }
}

文件 B:

struct secondView: View {
var body: some View {
    VStack {
    VStack(alignment: .leading) {
        Text("Turtle Rock")
            .font(.title)
        HStack(alignment: .top) {
            Text("Joshua Tree National Park")
                .font(.subheadline)
            Spacer()
            Text("California")
                .font(.subheadline)
        }
    }
    .padding()
        Spacer()

    }
  }
}                                                                                                  
于 2019-10-11T12:01:01.263 回答
3

OP 已在此处多次回答,但我只是想通过显示视图 A 中是否包含视图 B 也将使用的数据来演示 SwiftUI 的酷方面,您可以通过在视图 A 中创建 @State 来传递数据和在视图 B 中使用 @Binding 声明声明相同的变量

struct ViewA : View {
    @State var myItems: [Items]
    var body: some View {
        NavigationView {
            VStack {
                NavigationButton(destination: ViewB(items: $myItems)) {
                    Text("Go To ViewB")
                }
            }
        }
    }
}
struct ViewB : View {
    @Binding var myItems: [Items]
    var body: some View {
        NavigationView {
            List{
                ForEach(myItems.identified(by: \.self)) {
                    Text($0.itemName)
                }
            }.navigationBarTitle(Text("My Items"))
        }
    }
}
于 2019-06-11T16:44:58.087 回答
3

我认为这是最简单明了的方法。在 UI 工具之后使用fullScreenCover 。

Button(action: {
         //code
         }){
           Text("Send")
         }.fullScreenCover(isPresented: self.$model.goToOtherView, content: {
                    OtherView()
                })
于 2020-09-19T13:57:38.503 回答
2

我认为杰克的回答是 NextView 的基本方法。

如果你真的需要按下按钮,我认为下面的方式是一种简单、正式和动态的尝试方式。根据Paul Hudson 的视频,从 10'00" 到 12'00"。

(应该转到 12'00" 到 15'00",如果你想通过点击不同的按钮转到不同的视图。)(应该转到 15'00" 到 16'00",如果你想转到第二个视图并自动返回。)还有更多

这是代码示例。

import SwiftUI

struct ContentView: View {

    @State var areYouGoingToSecondView: Bool // Step 2

    var body: some View {
        NavigationView{ // Step 1

            VStack {

                // Step 3
                NavigationLink(destination: YourSecondView(), isActive: $areYouGoingToSecondView) { EmptyView() }


                Text("Hello World")

                Button(action: {
                    self.areYouGoingToSecondView = true // Step 4

                }) {
                    Text("Do Something (Go To Second View)")
                    .font(.largeTitle)
                    .fontWeight(.ultraLight)
                }
            }
        }
    }
}
于 2020-05-28T01:42:14.753 回答
1

您不能再使用 NavigationButton。相反,您应该使用 NavigationLink。

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailView()) {
                Text("Push new screen")
            }
        }
    }
}
于 2019-09-27T14:27:15.310 回答
1

我们可以在 Navigation 中使用 Text 并使其像 Button http://g.recordit.co/CkIkjvikfu.gif在此处输入图像描述

struct HomeContent: View {
    var body: some View {
        NavigationView{
            VStack {
                NavigationLink(
                destination: LoginContentView()) {
                    
                        
                           
                    Text("Login")
                        .font(.title)
                        .foregroundColor(Color.white)
                        .multilineTextAlignment(.center)
                        .frame(width: 300.0, height: 50.0)
                        .background(Color(UIColor.appLightBlue))
                   
                }
                
            }
        }
    }
}
于 2020-08-13T13:37:16.727 回答
1

要以编程方式导航到链接而不显示可视元素,请使用隐藏的NavigationLink.

在此示例中,UI 将在某些代码设置shouldNavigate为 true 时进行导航:

struct ProgramaticSample {
    @State var shouldNavigate = false
    
    var body: some View {
        Text("Hello navigation")
            .overlay(NavigationLink(
                destination: DestinationScreen(),
                isActive: $shouldNavigate) {}
                .hidden())
    }
}
于 2021-07-23T01:49:15.713 回答
0

必须创建一个像 LandmarkDetail() 这样的 DetailView,并调用一个以 LandmarkDetail() 为目标的 NavigationButton。现在详细视图已打开。

将值传递给详细屏幕意味着。通过发送如下代码。

struct LandmarkList: View {
    var body: some View {
        NavigationView {
            List(landmarkData) { landmark in
                NavigationButton(destination: LandmarkDetail()) {
                    LandmarkRow(landmark: landmark)
                }
            }
            .navigationBarTitle(Text("Landmarks"))
        }
    }
}
于 2019-06-04T12:43:28.043 回答