SwiftUI入門 - 1. 創(chuàng)建項目,xcode界面

置頂

菜鳥入門,各位大佬輕噴,如有謬誤之處歡迎討論建議,也歡迎各位道友與我同行

"不積跬步,無以至千里;不積小流,無以成江海"

繼續(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

總結

  1. TextField 的 .focused($focus, .name) 使用
  2. enum 的基本使用
  3. Alert 的基本使用
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容