简体   繁体   English

swiftui 中的视图更改

[英]Change of view in swiftui

my swift code below presents two views what I have to do is display the SecondViewController.我下面的 swift 代码提供了两个视图,我要做的是显示 SecondViewController。 Swift when tapped on the login button, how can I do it by implementing it in the code below? Swift 点击登录按钮时,如何通过在下面的代码中实现它来做到这一点? The code of the first view displays a login screen when clicking on the login button I must be push to SecondView.单击登录按钮时,第一个视图的代码显示登录屏幕,我必须将其推送到 SecondView。 I am new to swiftui我是 swiftui 的新手

SecondViewController.Swift SecondViewController.Swift

import SwiftUI
import MapKit

struct HomeView:  View {
    @State private var userTrackingMode: MapUserTrackingMode = .follow
    @State private var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(
            latitude: 25.7617,
            longitude: 80.1918
        ),
        span: MKCoordinateSpan(
            latitudeDelta: 10,
            longitudeDelta: 10
        )
    )

    var body: some View {
        Map(
            coordinateRegion: $region,
            interactionModes: MapInteractionModes.all,
            showsUserLocation: true,
            userTrackingMode: $userTrackingMode
        )
        
    }
}

struct HomeView_Previews: PreviewProvider {
    static var previews: some View {
        HomeView()
    }
}

MainView.swift主视图.swift

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        ZStack{
            
            LinearGradient(gradient: .init(colors: [Color("Color"),Color("Color1"),Color("Color2")]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(.all)
            
            if UIScreen.main.bounds.height > 800{
                
                Home()
            }
            else{
                
                ScrollView(.vertical, showsIndicators: false) {
                    
                    Home()
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Home : View {
    
    @State var index = 0
    @State var showingDetail = false
    @State var isModal: Bool = false
    
    
    
    func login(){
    
    }
    
    var body : some View{
        
        VStack{
            
            Image("logo")
            .resizable()
            .frame(width: 200, height: 180)
            
            HStack{
                
                Button(action: {
                    
                    withAnimation(.spring(response: 0.8, dampingFraction: 0.5, blendDuration: 0.5)){
                     
                       self.index = 0
                    }
                    
                    
                }) {
                    
                    Text("Login")
                        .foregroundColor(self.index == 0 ? .black : .white)
                        .fontWeight(.bold)
                        .padding(.vertical, 10)
                        .frame(width: (UIScreen.main.bounds.width - 50) / 2).sheet(isPresented: $isModal, content: {
                            
                        })
                    
                }.background(self.index == 0 ? Color.white : Color.clear)
                .clipShape(Capsule())
                
                Button(action: {
                   withAnimation(.spring(response: 0.8, dampingFraction: 0.5, blendDuration: 0.5)){
                       
                      self.index = 1
                   }
                    
                }) {
                    
                    Text("New User")
                        .foregroundColor(self.index == 1 ? .black : .white)
                        .fontWeight(.bold)
                        .padding(.vertical, 10)
                        .frame(width: (UIScreen.main.bounds.width - 50) / 2)
                    
                }.background(self.index == 1 ? Color.white : Color.clear)
                .clipShape(Capsule())
                
            }.background(Color.black.opacity(0.1))
            .clipShape(Capsule())
            .padding(.top, 25)
            
            if self.index == 0{
                
                Login(mail: "", pass: "", areYouGoingToSecondView: false)
                
            }
            else{
                
                SignUp()
            }
            
            if self.index == 0{
                
                Button(action: {
                    
                }) {
                    
                    Text("Forget Password?")
                        .foregroundColor(.white)
                
                }
                .padding(.top, 20)
            }
            
        }
        .padding()
    }
}

struct Login : View {
    
    @State var mail = ""
    @State var pass = ""
    @State var areYouGoingToSecondView: Bool=false
    
    var body : some View{
        
        VStack{
            
            VStack{
                
                HStack(spacing: 15){
                    
                    Image(systemName: "envelope")
                        .foregroundColor(.black)
                    
                    TextField("Enter Email Address", text: self.$mail)
                    
                }.padding(.vertical, 20)
                
                Divider()
                
                HStack(spacing: 15){
                    
                    Image(systemName: "lock")
                    .resizable()
                    .frame(width: 15, height: 18)
                    .foregroundColor(.black)
                    
                    SecureField("Password", text: self.$pass)
                    
                    Button(action: {
                        
                    }) {
                        
                        Image(systemName: "eye")
                            .foregroundColor(.black)
                    }
                    
                }.padding(.vertical, 20)
                
            }
            .padding(.vertical)
            .padding(.horizontal, 20)
            .padding(.bottom, 40)
            .background(Color.white)
            .cornerRadius(10)
            .padding(.top, 25)
            
    
            
            Button(action: {
                print("Prova di stampa")
            }) {
          
                Text("LOGIN")
                    .foregroundColor(.white)
                    .fontWeight(.bold)
                    .padding(.vertical)
                    .frame(width: UIScreen.main.bounds.width - 100)
                
                
            }.background(
            
                LinearGradient(gradient: .init(colors: [Color("Color2"),Color("Color1"),Color("Color")]), startPoint: .leading, endPoint: .trailing)
            )
            .cornerRadius(8)
            .offset(y: -40)
            .padding(.bottom, -40)
            .shadow(radius: 15)
        }
    }
}

struct SignUp : View {
    
    @State var mail = ""
    @State var pass = ""
    @State var checkpass = ""
    @State var repass = ""
    @State var name = ""
    @State var surname = ""
    
    var body : some View{
        
        VStack{
            
            VStack{
                
                HStack(spacing: 15){
                    
                    Image(systemName: "envelope")
                        .foregroundColor(.black)
                    
                    TextField("Enter Email Address", text: self.$mail)
                    
                }.padding(.vertical, 20)
                
                Divider()
                
                HStack(spacing: 15){
                    
                    Image(systemName: "person")
                    .resizable()
                    .frame(width: 15, height: 18)
                    .foregroundColor(.black)
                    
                    TextField("Enter Name", text: self.$name)
                    
            
                    
                }.padding(.vertical, 20)
                
                
                Divider()
                
                HStack(spacing: 15){
                    
                    Image(systemName: "person")
                    .resizable()
                    .frame(width: 15, height: 18)
                    .foregroundColor(.black)
                    
                    TextField("Enter Surname", text: self.$surname)
                    
            
                    
                }.padding(.vertical, 20)
                
                
                
                HStack(spacing: 15){
                    
                    Image(systemName: "lock")
                    .resizable()
                    .frame(width: 15, height: 18)
                    .foregroundColor(.black)
                    
                    SecureField("Password", text: self.$pass)
                    
                    Button(action: {
                        
                    }) {
                        
                        Image(systemName: "eye")
                            .foregroundColor(.black)
                    }
                    
                }.padding(.vertical, 20)
                
                Divider()
                HStack(spacing: 15){
                    
                    Image(systemName: "lock")
                    .resizable()
                    .frame(width: 15, height: 18)
                    .foregroundColor(.black)
                    
                    SecureField("Re-Enter Password", text: self.$checkpass)
                    
                    Button(action: {
                        
                    }) {
                        
                        Image(systemName: "eye")
                            .foregroundColor(.black)
                    }
                    
                }.padding(.vertical, 20)
                
              
            }
            .padding(.vertical)
            .padding(.horizontal, 20)
            .padding(.bottom, 40)
            .background(Color.white)
            .cornerRadius(10)
            .padding(.top, 25)
            
            
            
            //Button for signup user
            Button(action: {
                
            }) {
                
                Text("SIGNUP")
                    .foregroundColor(.white)
                    .fontWeight(.bold)
                    .padding(.vertical)
                    .frame(width: UIScreen.main.bounds.width - 100)
                
            }.background(
            
                LinearGradient(gradient: .init(colors: [Color("Color2"),Color("Color1"),Color("Color")]), startPoint: .leading, endPoint: .trailing)
            )
            .cornerRadius(8)
            .offset(y: -40)
            .padding(.bottom, -40)
            .shadow(radius: 15)
        }
    }
}

The two main ways to do this, as I understand, are:据我了解,执行此操作的两种主要方法是:

  1. use a NavigationView to wrap your Home() content, then use NavigationLink to replace one view with another (I am trying NavigationStackView from this library , which works similarly)使用NavigationView来包装您的Home()内容,然后使用NavigationLink将一个视图替换为另一个视图(我正在尝试使用此库中的NavigationStackView ,其工作方式类似)
  2. use a @State variable in your ContentView class, and change it on successful login.ContentView class 中使用@State变量,并在成功登录时更改它。 You can use an Int index, or better yet, an enum :您可以使用Int索引,或者更好的是enum
enum MyViews {
    case home
    case secondView
    case someOtherView
}

struct ContentView: View {

    @State var viewToShow : MyViews
    var body: some View {
        
        if viewToShow == .home {
            ZStack{
            
                if UIScreen.main.bounds.height > 800{
                    Home()
                } else {
                    ScrollView(.vertical, showsIndicators: false) {
                        Home()
                    }
                }
            }
        } else if viewToShow == .secondView {
            HomeView()
        } else {
            Text("I'm not sure what to show you here")
        }
    }
}

You will need to decide how you want your Login button to report a change of state to its parent view, but hopefully this helps.您需要决定如何让您的登录按钮将 state 的更改报告到其父视图,但希望这会有所帮助。

Just to add to what John suggested, it might be worth creating an Observable class to use as an environment object so that many views can access and change the page.只是为了补充 John 的建议,可能值得创建一个 Observable class 用作环境 object 以便许多视图可以访问和更改页面。 Something like:就像是:

enum Page {
case login
case home
case secondView
case someOtherView
}

class AppController: ObservableObject {
    
    // private(set) will mean you can only change pageControl
    // within this class (AppController) which will help prevent
    // bugs but remove if not necessary
    @Published private(set) var pageControl: Page
    @Published var isLoggedIn: Bool
    
    init() {
        self.pageControl = .login
        self.isLoggedIn = false
    }
    
    func someLoginFunction() {
        // will call self.changePage(.home) if login succeeds
        // and isLoggedIn to true
    }
    
    func changePage(_ page: Page) {
        self.pageControl = page
    }
}

struct ContentView: View {
        var controller = AppController()
        
        var body: some View {
            VStack {
                switch controller.pageControl {
                    case .login:
                        LoginView().environmentObject(controller)
                    case .home:
                        Home().environmentObject(controller)
                    default:
                        EmptyView()
                    }
                }
        }
    }

I used a switch statement instead of an If statement which does the same thing, just a bit neater:) The default in there is only needed at the moment because I haven't accounted for all the possibilities within the enum Page.我使用了 switch 语句而不是 If 语句,它做同样的事情,只是更简洁一点:) 那里的默认值目前只需要,因为我没有考虑枚举页面中的所有可能性。 Once you create cases for all the different pages, it shouldn't be needed!一旦为所有不同的页面创建案例,就不需要它了!

In terms of the AppController, this could be your hub for controlling your app.就 AppController 而言,这可能是您控制应用程序的中心。 The @Published variables will update all the views that use them when it is updated (like @State). @Published 变量将在更新时更新所有使用它们的视图(如@State)。 Sorry if I'm teaching fish to swim here, I just want to be thorough and you said you're new to swiftUI!对不起,如果我在这里教鱼游泳,我只是想彻底,你说你是 swiftUI 的新手!

You will need to pass the AppController into every view you'd like to use it in like I have in the switch statement.您需要将 AppController 传递到您想要使用它的每个视图中,就像我在 switch 语句中所做的那样。 Within the view you'd like to be able to use the AppController, you will need this line:在您希望能够使用 AppController 的视图中,您将需要这一行:

@EnvironmentObject var controller: AppController

And then you can access everything inside it by calling controller!然后你可以通过调用控制器来访问它里面的所有东西!

Any more questions, please let me know.还有什么问题,请告诉我。 Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM