簡體   English   中英

如何將我的環境 object 設置為 SwiftUI 中的用戶輸入?

[英]How do I set my environment object to user input in SwiftUI?

我目前正在使用選項卡視圖在項目中的 4 個視圖之間導航,初始視圖是我的 profileView,我希望用戶在其中輸入他們的信息和目標,例如年齡、身高等。**但是我真的很難找到有關如何獲取用戶輸入並將我的環境 object 設置為該用戶輸入的良好示例和說明。 我正在考慮只使用 forms,但這似乎沒有必要,而且我不太確定如何將環境 object 更改為用戶設置的環境。 有沒有人可以參考我的任何好的文檔,或者向我展示如何獲取用戶輸入並將我的環境 object 設置為該數據的示例。 (我也不確定這是否有必要,因為我稍后也會將它存儲在 userdefaults 或 coredata 中。

這是我的 model class 這是我為用戶提供的 class 數據。 暫時忽略底部的設置值,項目后期開發時全部設置為空。

class UserInfoModel: ObservableObject {
    
    
    struct UserInfo: Identifiable {
        var id = UUID()
        var firstName: String
        var lastName: String
        var height: Int
        var weight: Int
        var gender: String
        var age: Int
        
    }
    
    struct DailyCalorieGoals: Identifiable{
        var id = UUID()
        var calorieGoal: Int
        var fatGoal: Int
        var proteinGoal: Int
        var carbGoal: Int

    }
    
    struct CurrentCalorieProgress: Identifiable{
        var id = UUID()
        var calorieProgress: Int
        var fatProgress: Int
        var carbProgress: Int
    }
    
    @Published var personUserInfo = UserInfo.init(firstName: "", lastName:"", height: 0, weight: 0, gender: "", age: 0)
    @Published var personDailyCalorieGoals = DailyCalorieGoals.init(calorieGoal: 2400, fatGoal: 0, proteinGoal: 0, carbGoal: 0)
    @Published var personCurrentCalorieProgress = CurrentCalorieProgress.init(calorieProgress: 0, fatProgress: 0, carbProgress: 0)
    
   
}

那么當我在我的個人資料視圖中時,我如何獲取用戶輸入並將我的環境 object 設置為該數據?

由於到目前為止提供的幫助,上述問題已經解決,但是使用下面鏈接的方法我得到以下內容,但我不確定如何將我的雙環境 object 的值更改為 fatInputString:

獲取用戶輸入的新代碼

Text("Fat: \(self.person.personDailyCalorieGoals.fatGoal, specifier: "%.0f")g")
                            }
                            TextField("Enter new fat goal (g)", text: $fatInputString ).keyboardType(.numberPad)
                                .onReceive(Just(fatInputString)) { newValue in
                                                let filtered = newValue.filter { "0123456789".contains($0) }
                                                if filtered != newValue {
                                                    self.fatInputString = filtered
                                                }

但是我如何設置我的環境 object

self.person.personDailyCalorieGoals.fatGoal 

等於

self.inputString 

從上面的代碼}

不需要使用Form ——它只是讓用戶輸入元素的格式在 iOS/macOS 上更加標准化。

無論您是否使用Form ,您都將使用各種用戶輸入元素並在您的UserInfoModel上為它們分配綁定。 SwiftUI/Combine 使用$運算符使這非常容易。

這是一個如何獲取幾個字段輸入的示例。 可以看到,當字段信息發生變化時,值會反映在ContentView擁有的EnvironmentObject中——它顯示在EditorView上方的頂部

struct ContentView : View {
    @ObservedObject var userInfo = UserInfoModel()
    
    var body: some View {
        VStack {
            Text("Name: \(userInfo.personUserInfo.firstName)")
            Text("Weight: \(userInfo.personUserInfo.weight)")
            Text("Carb: \(userInfo.personCurrentCalorieProgress.carbProgress)")
            EditorView().environmentObject(userInfo)
        }
    }
}

struct EditorView : View {
    @EnvironmentObject private var userInfo : UserInfoModel
    
    var body: some View {
        Form {
            TextField("First name", text: $userInfo.personUserInfo.firstName)
            Stepper("Weight", value: $userInfo.personUserInfo.weight, in: 0...500)
            Stepper("Carb progress", value: $userInfo.personCurrentCalorieProgress.carbProgress, in: 0...1000, step: 10)
        }
    }
}

根據評論更新:編輯以顯示您對數字文本輸入的請求:

struct EditorView : View {
    @EnvironmentObject private var userInfo : UserInfoModel
    @State var fatInputString = "" //<-- Here
    
    var body: some View {
        Form {
            TextField("First name", text: $userInfo.personUserInfo.firstName)
            Stepper("Weight", value: $userInfo.personUserInfo.weight, in: 0...500)
            Stepper("Carb progress", value: $userInfo.personCurrentCalorieProgress.carbProgress, in: 0...1000, step: 10)
            Text("Fat: \(userInfo.personDailyCalorieGoals.fatGoal)g") //<-- Here
            TextField("Enter new fat goal (g)", text: $fatInputString ).keyboardType(.numberPad)
                .onReceive(Just(fatInputString)) { newValue in
                    let filtered = newValue.filter { "0123456789".contains($0) }
                    if filtered != newValue {
                        self.fatInputString = filtered
                    }
                    if let goal = Int(fatInputString), goal != userInfo.personDailyCalorieGoals.fatGoal {  //<-- Here
                        userInfo.personDailyCalorieGoals.fatGoal = goal
                    }
                }
        }
        
    }
}

請注意,在您更新的代碼中,您有一個錯誤,即脂肪量始終顯示為 0。確保查看每一行帶有//<-- Here標記

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM