import SwiftUI struct AirConditionerView: View { @ObservedObject var viewModel: AirConditionerViewModel @FocusState var tempTextFieldIsFocused: Bool var body: some View { VStack(spacing: 15) { // MARK: - 1. Power Toggle Toggle("Power", isOn: $viewModel.airConditionerIsOn) // MARK: - 2. AC Mode picker HStack { Text("Mode") Picker("Mode", selection: $viewModel.airConditionerMode) { ForEach(AirConditionerViewModel.AirConditionerMode.allCases) { mode in Text(mode.rawValue) } }.pickerStyle(.segmented) }.disabled(!viewModel.airConditionerIsOn) // MARK: - 3. Temperature text field HStack { Text("Temperature") TextField("", value: $viewModel.desiredTemperature, formatter: NumberFormatter()) .padding(.leading) .border(.primary) .focused($tempTextFieldIsFocused) }.disabled(!viewModel.airConditionerIsOn) // MARK: - 4. Temperature slider Slider(value: $viewModel.desiredTemperature, in: viewModel.minTemperature...viewModel.maxTemperature, onEditingChanged: { editing in if editing { tempTextFieldIsFocused = false } }).disabled(!viewModel.airConditionerIsOn) // MARK: - 5. Fan power toggle Toggle("Fan", isOn: $viewModel.fanIsOn) .disabled(!viewModel.airConditionerIsOn) // MARK: - 6. Fan speed picker HStack { Text("Fan Speed") Spacer() }.disabled(!viewModel.airConditionerIsOn) Picker("Mode", selection: $viewModel.fanSpeed) { ForEach(AirConditionerViewModel.FanSpeed.allCases) { speed in Text(speed.rawValue) } } .pickerStyle(.segmented) .disabled(!viewModel.airConditionerIsOn) // MARK: - 7. AC status Images HStack { switch viewModel.airConditionerMode { case .cool: Image("snowflake") .resizable() .scaledToFit() .frame(width: 150, height: 150) case .heat: Image("heating") .resizable() .scaledToFit() .frame(width: 150, height: 150) } if viewModel.fanIsOn { VStack { Image("fan") .resizable() .scaledToFit() .frame(width: 100, height: 100) switch viewModel.fanSpeed { case .low: Text("1x") case .medium: Text("2x") case .high: Text("3x") } } .frame(width: 150, height: 150) } else { Rectangle() .foregroundColor(.clear) .frame(width: 150, height: 150) } } // MARK: - 8. Progress Bar HStack { VStack { Text("Current") Text(String(format: "%.2f", viewModel.currentTemperature)) .frame(width: 50, height: 5) } ProgressView(value: viewModel.currentTemperature, total: viewModel.desiredTemperature) .scaleEffect(x: 1, y: 5, anchor: .center) VStack { Text("Goal") Text(String(format: "%.2f", viewModel.desiredTemperature)) .frame(width: 50, height: 5) } } } } }
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter