置頂
菜鳥入門,各位大佬輕噴,如有謬誤之處歡迎討論建議,也歡迎各位道友與我同行
"不積跬步,無以至千里;不積小流,無以成江海"
繼續(xù)
續(xù)接上篇文章,我們實現了一個簡單的登陸界面,但是我們的表單提示,例如用戶名等,是用的文字在按鈕上方提示的
那我們如何去實現一個提示框用于提示呢?然后再自動聚焦到輸入框中呢?
提示框的實現
// 是否顯示彈窗的標識
@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("確定")){
}
)
}
以上的代碼運行后得到如下結果
3d210ff5ae404a87bd6700e833f1f6b1.png
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()
}
}
運行得到以下的結果
iShot_2022-11-08_21.57.35.gif
總結
- TextField 的 .focused($focus, .name) 使用
- enum 的基本使用
- Alert 的基本使用