J'ai une vue de base avec un bouton utilisant SwiftUI et j'essaie de présenter un nouvel écran/vue lorsque le bouton est appuyé. Comment puis-je faire cela? Suis-je supposé créer un délégué pour cette vue qui dira à l'application SceneDelegate
de présenter un nouveau contrôleur de vue?
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)
}
}
}
}
La clé est d'utiliser un NavigationView et un NavigationLink:
import SwiftUI
struct ContentView : View {
var body: some View {
NavigationView {
VStack {
Text("Hello World")
NavigationLink(destination: DetailView()) {
Text("Do Something")
}
}
}
}
}
Voici une autre façon de présenter une vue SANS utiliser NavigationView. C'est comme UIKit UIModalPresentationStyle.currentContext
.
struct PresenterButtonView: View {
var body: some View {
PresentationButton(Text("Tap to present"),
destination: Text("Hello world"))
}}
J'ai fait un ViewModifier
pour cela. Cela signifie également qu'il n'y a pas de barre de navigation. Vous pouvez l'appeler ainsi:
.navigate(to: MainPageView(), when: $willMoveToNextScreen)
Cela peut être attaché à n'importe quoi, donc je l'attache généralement à l'extrémité du corps, par exemple:
@State private var willMoveToNextScreen = false
var body: some View {
VStack {
/* ... */
}
.navigate(to: MainPageView(), when: $willMoveToNextScreen)
}
Code (n'oubliez pas de 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()
}
}
}
}
}
L'OP a été répondu plusieurs fois ici, mais je voulais simplement démontrer les aspects sympas de SwiftUI en montrant si vous avez la vue A avec des données que la vue B utilisera également, vous pouvez transmettre des données en créant un @State dans la vue A et déclarant la même variable avec la déclaration @Binding dans la vue B
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"))
}
}
}
Maintenant, nous pouvons utiliser NavigationLink
Déposer un:
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)
}
}
}
}
}
Fichier 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()
}
}
}
Vous ne pouvez plus utiliser NavigationButton. À la place, vous devez utiliser NavigationLink.
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailView()) {
Text("Push new screen")
}
}
}
}
Vous devez créer un DetailView comme LandmarkDetail () et appeler un NavigationButton avec destination comme LandmarkDetail (). La vue détaillée était maintenant ouverte.
Pour passer des valeurs aux détails de l'écran signifie. en envoyant comme ci-dessous le code.
struct LandmarkList: View {
var body: some View {
NavigationView {
List(landmarkData) { landmark in
NavigationButton(destination: LandmarkDetail()) {
LandmarkRow(landmark: landmark)
}
}
.navigationBarTitle(Text("Landmarks"))
}
}
}