swiftui 如何自己关闭scene窗口(SwiftUI入门-3.)
菜鸟入门,各位大佬轻喷,如有谬误之处欢迎讨论建议,也欢迎各位道友与我同行
"不积跬步,无以至千里;不积小流,无以成江海"
继续续接上篇文章,我们实现了一个简单的登陆界面,但是我们的表单提示,例如用户名等,是用的文字在按钮上方提示的
那我们如何去实现一个提示框用于提示呢?然后再自动聚焦到输入框中呢?
提示框的实现
// 是否显示弹窗的标识 @State private var showalert:Bool = false; // 在登陆按钮之后放置弹窗 Button("登陆"){ // 切换要显示Alert showAlert.toggle(); // 省略一部分操作。。。 }.alert(isPresented: $showAlert){ // 这里 isPresented 绑定 showAlert变量 Alert( title: Text("提示"), // 顶部的标题 message: Text(res), // 弹窗的内容,需要是一个Text,调用了我们之前定义的提示文本 primaryButton: .default(Text("取消")){// 第一个按钮是默认类型样式,显示取消 // 第一个按钮点击后的操作 }, secondaryButton: .destructive(Text("确定")){ } ) }
以上的代码运行后得到如下结果
在这里插入图片描述
focus 到TextField以上的弹出框提示已经解决,那么接下来需要实现的是弹出之后哪一个字段没填,就让它自动聚焦,让用户可以直接填写那个字段 添加如下的代码
// 是否聚焦到用户名字段,注意@符号后面跟的是 FocusState,不然用到focused里面会报错,并且不能设置默认值 @FocusState private var focusUser:Bool; HStack{ Text("用户名") Spacer() TextField("请输入用户名",text:$userName) .multilineTextAlignment(.center) // 给用户名字段的 focused 绑定 focusUser 变量 .focused($focusUser) }.padding(.all) } /// ... 省略部分代码 Button("登陆"){ // 切换要显示Alert showAlert.toggle(); if(userName == ""){ // 如果没填 userName 那么切换 focusUser 的值 focusUser.toggle() } // 省略一部分操作。。。 } // 。。。 省略Alert部分
此处的代码实现了,如果在点击登陆按钮后用户名没有填,自动聚焦到用户名字段
在本页面中,共有三个字段,可以定义三个变量的形式来进行判定聚焦
但是如果有很多个字段的话就不合适了,我们可以使用枚举的方式来进行定义
以下贴出本页面完整的代码
import SwiftUI struct ContentView: View { // 用户名 @State private var userName:String = ""; // 密码 @State private var passWord:String = ""; // 验证码 @State private var code:String = ""; // 提示语 @State private var res:String = "请输入。。。"; // 提示语的颜色,color类型 @State private var color:Color = .red; // 是否显示弹窗标识 @State private var showAlert:Bool = false; // 聚焦到哪一个字段? @FocusState private var focus:FocusField?; // 定义一个 Hashable 的枚举,因为 focused 的第二个参数需要一个hashable的参数 enum FocusField:Hashable{ case name; case password; case code; case clear; }; var body: some View { // 整体纵向布局 VStack { // 页面标题,加粗,标题字体 Text("登陆界面").fontWeight(.bold).font(.title) // 分隔占位,有点类似html中flex的flex:1,具体怎么用之后再看 Spacer() // 一个横向布局,表单项名称-分隔占位-以及表单项 // 给一个 .all 的 padding,不然不好看 HStack{ Text("用户名") Spacer() TextField("请输入用户名",text:$userName) .multilineTextAlignment(.center) // focused 绑定 focus变量,当该变量为 .name 时 .focused($focus,equals: .name) }.padding(.all) HStack{ Text("密码") Spacer() // secure field 跟 TextField基本类似,只是隐藏输入的内容 SecureField("请输入密码",text:$passWord) .multilineTextAlignment(.center) .focused($focus, equals: .password) }.padding(.all) HStack{ Text("验证码") Spacer() TextField("请输入验证码",text:$code) .multilineTextAlignment(.center) .focused($focus, equals: .code) }.padding(.all) Spacer() // 提示语和button在一起 Text(res).foregroundColor(color) Button("登陆"){ showAlert.toggle(); color = .red // button 的点击事件action,做一个简单的判断 // 修改 res 的名称,以及res的颜色 if(userName == ""){ res = "请输入用户名!"; return ; } if(passWord == ""){ res = "请输入密码!" return ; } if(code == ""){ res = "请输入验证码"; return ; } color = .green; res = "登陆成功" // 清空表单数据 userName = ""; passWord = ""; code = ""; }.buttonStyle(.bordered) .alert(isPresented: $showAlert){ Alert( title: Text("提示"), message: Text(res), primaryButton: .default(Text("取消")), secondaryButton: .destructive(Text("确定")){ if(res == "请输入用户名!"){ // 没有用户名 focus = .name } if(res == "请输入密码!"){ focus = .password } if(res == "请输入验证码!"){ focus = .code } if(res == "登陆成功" || res == "请输入。。。"){ focus = .clear } } ) } } .padding() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
运行得到以下的结果
在这里插入图片描述
总结,
- TextField 的 .focused($focus, .name) 使用
- enum 的基本使用
- Alert 的基本使用
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com