[英]Change of view in swiftui
我下面的 swift 代码提供了两个视图,我要做的是显示 SecondViewController。 Swift 点击登录按钮时,如何通过在下面的代码中实现它来做到这一点? 单击登录按钮时,第一个视图的代码显示登录屏幕,我必须将其推送到 SecondView。 我是 swiftui 的新手
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()
}
}
主视图.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)
}
}
}
据我了解,执行此操作的两种主要方法是:
NavigationView
来包装您的Home()
内容,然后使用NavigationLink
将一个视图替换为另一个视图(我正在尝试使用此库中的NavigationStackView
,其工作方式类似)ContentView
class 中使用@State
变量,并在成功登录时更改它。 您可以使用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")
}
}
}
您需要决定如何让您的登录按钮将 state 的更改报告到其父视图,但希望这会有所帮助。
只是为了补充 John 的建议,可能值得创建一个 Observable class 用作环境 object 以便许多视图可以访问和更改页面。 就像是:
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()
}
}
}
}
我使用了 switch 语句而不是 If 语句,它做同样的事情,只是更简洁一点:) 那里的默认值目前只需要,因为我没有考虑枚举页面中的所有可能性。 一旦为所有不同的页面创建案例,就不需要它了!
就 AppController 而言,这可能是您控制应用程序的中心。 @Published 变量将在更新时更新所有使用它们的视图(如@State)。 对不起,如果我在这里教鱼游泳,我只是想彻底,你说你是 swiftUI 的新手!
您需要将 AppController 传递到您想要使用它的每个视图中,就像我在 switch 语句中所做的那样。 在您希望能够使用 AppController 的视图中,您将需要这一行:
@EnvironmentObject var controller: AppController
然后你可以通过调用控制器来访问它里面的所有东西!
还有什么问题,请告诉我。 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.