web-dev-qa-db-ja.com

SwiftUIを使用して新しいビューに移動する

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

重要なのは、NavigationViewとNavigationLinkを使用することです。

import SwiftUI

struct ContentView : View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello World")
                NavigationLink(destination: DetailView()) {
                    Text("Do Something")
                }
            }
        }
    }
}
17
Jake

NavigationViewを使用せずにビューを表示する別の方法を次に示します。これはUIKitのUIModalPresentationStyle.currentContextに似ています。

struct PresenterButtonView: View {
var body: some View {
    PresentationButton(Text("Tap to present"),
                       destination: Text("Hello world"))
}}
8
SMP

私はこれのために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()
                }
            }
        }
    }
}
3
George_E

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"))
        }
    }
}
2
nikoclicks

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

    }
  }
}                                                                                                  
1

NavigationButtonは使用できなくなりました。代わりに、NavigationLinkを使用する必要があります。

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailView()) {
                Text("Push new screen")
            }
        }
    }
}
0
Edward

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