SwiftUI按钮更改视图

16

我了解在最新的SwiftUI中有PresentationButtonNavigationButton用于更改视图。然而,我想执行如下简单的操作。当用户点击“登录”按钮时,如果凭据正确,则将其登录,但还要执行一个segue(在此情况下更改视图)。 但是我无法在PresentationButton中检查它们是否正确,并且我无法在普通按钮中更改视图。

有没有其他方法可以做到这一点?


  @IBAction func signInClicked(_ sender: Any) {
        
        if emailText.text != "" && passwordText.text != "" {
            
            Auth.auth().signIn(withEmail: emailText.text!, password: passwordText.text!) { (userdata, error) in
                if error != nil {
                   //error
                } else {
                   performSegue(withIdentifier: "toFeedActivity", sender: nil)
                }
            }
        } else {
            //error
        }
    }

我猜你已经知道你正在发布 UIKit 代码,而不是 SwiftUI 代码。话虽如此,你能否发布你的 SwiftUI 代码呢?另外,你有没有尝试在这个网站上搜索?一个非常快速的搜索 *"[SwiftUI] login" 就会返回两天前针对你的问题的一个被接受的答案。如果它不能解决你的问题,你能否更具体地描述一下? - user7014451
4个回答

36

这里有一种方式。

struct AppContentView: View {
    
    @State var signInSuccess = false
    
    var body: some View {
        return Group {
            if signInSuccess {
                AppHome()
            }
            else {
                LoginFormView(signInSuccess: $signInSuccess)
            }
        }
    }
}

struct LoginFormView : View {
    
    @State private var userName: String = ""
    @State private var password: String = ""
    
    @State private var showError = false
    
    @Binding var signInSuccess: Bool
    
    var body: some View {
        VStack {
            HStack {
                Text("User name")
                TextField("type here", text: $userName)
            }.padding()
            
            HStack {
                Text(" Password")
                TextField("type here", text: $password)
                    .textContentType(.password)
            }.padding()
            
            Button(action: {
                // Your auth logic
                if(self.userName == self.password) {
                    self.signInSuccess = true
                }
                else {
                    self.showError = true
                }
                
            }) {
                Text("Sign in")
            }
            
            if showError {
                Text("Incorrect username/password").foregroundColor(Color.red)
            }
        }
    }
}

struct AppHome: View {
    
    var body: some View {
        VStack {
        Text("Hello freaky world!")
        Text("You are signed in.")
        }
    }
}


3
有没有办法让这个过渡动画化? - Dmitry Serov
1
这个解决方案不仅通过切换变量来切换内容,而且还可以改变整个视图。非常有帮助! - Veck Hsiao
非常感谢,这对我在使用NavigationView时遇到“无法呈现,请提交错误”错误时非常有帮助。 - Tien Do

7

在我的一个应用中,我也有同样的需求,并且找到了解决方案...

基本上,您需要将主视图插入到NavigationView中,然后在视图中添加一个不可见的NavigationLink,创建一个控制何时推送视图并在登录回调中更改其值的@state变量...

这是代码:

struct ContentView: View {
    @State var showView = false
    var body: some View {
        NavigationView {
            VStack {
                Button(action: {
                    print("*** Login in progress... ***")
                    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                        self.showView = true
                    }
                }) {
                    Text("Push me and go on")
                }

                //MARK: - NAVIGATION LINKS
                NavigationLink(destination: PushedView(), isActive: $showView) {
                    EmptyView()
                }
            }
        }
    }
}


struct PushedView: View {
    var body: some View {
        Text("This is your pushed view...")
            .font(.largeTitle)
            .fontWeight(.heavy)
    }
}

NavigationView和链接(或缺乏链接)是我的问题所在。之前已经解决了身份验证部分,但无法在成功验证后更改页面/UI。 - Nubtacular

2

尝试使用state和.sheet

struct ContentView: View {
    @State var showingDetail = false

    var body: some View {
        Button(action: {
            self.showingDetail.toggle()
        }) {
            Text("Show Detail")
        }.sheet(isPresented: $showingDetail) {
            DetailView()
        }
    }
}

2
以下是如何撰写一个好的回答?的一些指南。这个提供的答案可能是正确的,但它可以从解释中受益。仅有代码的答案不被认为是“好”的答案。来自审查 - Trenton McKinney
1
这不是OP想要实现的。这将创建一个模态而不是UIKit中预期的“segue”。 - Mattia Righetti

-1

你可以使用带标签的导航链接,代码如下:

首先,声明标签变量

@State var tag : Int? = nil

然后创建您的按钮视图:

Button("Log In", action: {
                        Auth.auth().signIn(withEmail: self.email, password: self.password, completion: { (user, error) in
                            if error == nil {
                                self.tag = 1
                                print("success")
                            }else{
                                print(error!.localizedDescription)
                            }
                        })

当登录成功时,标签将变为1,当标签变为1时,您的导航链接将被执行

导航链接代码:

NavigationLink(destination: HomeView(), tag: 1, selection: $tag) {
                EmptyView()
                }.disabled(true)

如果你正在使用表单,请使用.disabled,因为在这里空视图将显示在表单上,你不希望用户点击它并转到homeView。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接