[英]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.