如何对绑定或状态进行价值转换

时间:2019-11-14 07:08:11

标签: ios swift swiftui

我试图了解如何将价值从模型转换为视图。例如,我有一个模型:

struct BloodPressure {  
    var systolic: Int = 0
    var diastolic: Int = 0
}

我有一个看法:

struct MeasurementsTabView: View {
    @State private var bloodPressure = BloodPressure()

    var body: some View {
        VStack {
            TextField("Systolic", text: $bloodPressure.systolic)
            TextField("Diastolic", text: $bloodPressure.diastolic)
        }
    }
}

出现错误,因为text参数应该是字符串,但是bloodPressure.systolicInt

我找到了一个解决方案,但我认为这并不优雅:

var body: some View {
    let systolicBinding = Binding <String> (
        get: { String(self.bloodPressure.systolic) },
        set: {
            if let int = Int($0) {
                self.bloodPressure.systolic = int
            }
        })

    let diastolicBinding = Binding <String> (
        get: { String(self.bloodPressure.diastolic) },
        set: {
            if let int = Int($0) {
                self.bloodPressure.diastolic = int
            }
        })

    return VStack {
        TextField("Systolic", text: systolicBinding)
        TextField("Diastolic", text: diastolicBinding)
    }
}

您如何解决类似问题?

1 个答案:

答案 0 :(得分:2)

在这种情况下,我建议引入ViewModel层,以便BloodPressure保持纯模型。

下面是概念的简化演示(例如,文本字段的格式设置/验证超出范围等)

import SwiftUI
import Combine

struct BloodPressure {
    var systolic: Int = 0
    var diastolic: Int = 0
}

class BloodPressureViewModel: ObservableObject {
    var model: BloodPressure

    init(_ model: BloodPressure) {
        self.systolic = String(model.systolic)
        self.diastolic = String(model.diastolic)

        self.model = model
    }
    @Published var systolic: String = "" {
        didSet {
            self.model.systolic = Int(self.systolic) ?? 0
        }
    }
    @Published var diastolic: String = "" {
        didSet {
            self.model.diastolic = Int(self.diastolic) ?? 0
        }
    }
}


struct MeasurementsTabView: View {
    @ObservedObject var viewModel: BloodPressureViewModel

    init(bloodPressure: BloodPressure) {
        viewModel = BloodPressureViewModel(bloodPressure)
    }
    var body: some View {
        VStack {
            TextField("Systolic", text: $viewModel.systolic)
            TextField("Diastolic", text: $viewModel.diastolic)
        }
    }
}