Preview:
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)
                }
            }
        }
    }
}
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