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)
}
}
}
}
重要なのは、NavigationViewとNavigationLinkを使用することです。
import SwiftUI
struct ContentView : View {
var body: some View {
NavigationView {
VStack {
Text("Hello World")
NavigationLink(destination: DetailView()) {
Text("Do Something")
}
}
}
}
}
NavigationViewを使用せずにビューを表示する別の方法を次に示します。これはUIKitのUIModalPresentationStyle.currentContext
に似ています。
struct PresenterButtonView: View {
var body: some View {
PresentationButton(Text("Tap to present"),
destination: Text("Hello world"))
}}
私はこれのためにViewModifier
を作りました。また、ナビゲーションバーがないことも意味します。次のように呼び出すことができます。
.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<SomeView: View>(to view: SomeView, when binding: Binding<Bool>) -> some View {
modifier(NavigateModifier(destination: view, binding: binding))
}
}
// MARK: - NavigateModifier
fileprivate struct NavigateModifier<SomeView: View>: ViewModifier {
// MARK: Private properties
fileprivate let destination: SomeView
@Binding fileprivate var binding: Bool
// MARK: - View body
fileprivate func body(content: Content) -> some View {
NavigationView {
ZStack {
content
.navigationBarTitle("")
.navigationBarHidden(true)
NavigationLink(destination: destination
.navigationBarTitle("")
.navigationBarHidden(true),
isActive: $binding) {
EmptyView()
}
}
}
}
}
OPはここで複数回回答されていますが、ビューAにデータがあり、ビューBも使用するかどうかを示し、ビュー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"))
}
}
}
NavigationLinkを使用できるようになりました
ファイルA:
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()
}
}
}
NavigationButtonは使用できなくなりました。代わりに、NavigationLinkを使用する必要があります。
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailView()) {
Text("Push new screen")
}
}
}
}
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"))
}
}
}