SwiftUI Practice

SwiftUI DateTimeProductPicker

Today I created a SwiftUI project using 3 various Pickers and animated switching between the various pickers and animating the product image when selecting a new product.

import SwiftUI

struct ContentView: View {
  @Environment(\.colorScheme) var colorScheme
    
  @State private var selectedDate: Date = Date()
  @State private var selectedProduct = Product.products()[0]
  @State private var showingDatePicker = false
  @State private var showingTimePicker = false
  @State private var showingProductPicker = false
  
  private var duration: Double = 0.3
  let products = Product.products()
  
  var darkModeColor: Color {
    colorScheme == .dark ? .yellow : .blue
  }
  
  var body: some View {
    VStack {
      GroupBox {
        HStack {
          Text("Date")
          
          Spacer()
          
          Button("\(selectedDate.formatted(date: .long, time: .omitted))") {
            withAnimation {
              if showingTimePicker { showingTimePicker = false }
              if showingProductPicker { showingProductPicker = false }
              showingDatePicker.toggle()
            }
          }
          .foregroundStyle(showingDatePicker ? darkModeColor : .primary)
          .buttonStyle(.borderedProminent)
          .tint(.secondary.opacity(0.2))
        }
        .drawingGroup()
        
        if showingDatePicker {
          DatePicker(selection: $selectedDate, in: ...Date(), displayedComponents: .date) {
            Text("Date")
          }
          .datePickerStyle(.graphical)
          .tint(darkModeColor)
        }
        
        Divider()
        
        HStack {
          Text("Time")
          
          Spacer()
          
          Button("\(selectedDate.formatted(date: .omitted, time: .shortened))") {
            withAnimation {
              if showingDatePicker { showingDatePicker = false }
              if showingProductPicker { showingProductPicker = false }
              showingTimePicker.toggle()
            }
          }
          .foregroundStyle(showingTimePicker ? darkModeColor : .primary)
          .buttonStyle(.borderedProminent)
          .tint(.secondary.opacity(0.2))
        }
        .drawingGroup()
        
        if showingTimePicker {
          DatePicker(selection: $selectedDate, in: ...Date(), displayedComponents: .hourAndMinute) {
            Text("Time")
          }
          .labelsHidden()
          .datePickerStyle(.wheel)
        }
        
        Divider()
        
        HStack {
          Text("Product")
          
          Spacer()
          
          Button(selectedProduct.name) {
            withAnimation {
              if showingDatePicker { showingDatePicker = false }
              if showingTimePicker { showingTimePicker = false }
              showingProductPicker.toggle()
            }
          }
          .foregroundStyle(showingProductPicker ? darkModeColor : .primary)
          .buttonStyle(.borderedProminent)
          .tint(.secondary.opacity(0.2))
        }
        .drawingGroup()
        
        if showingProductPicker {
          Picker("Select a product", selection: $selectedProduct, content: {
            ForEach(products) { product in
              Text(product.name).tag(product)
            }
          })
          .pickerStyle(.wheel)
        }
      }
      .scrollBounceBehavior(.basedOnSize)
      
      Divider()
      
      VStack {
        Text(selectedProduct.name)
          .font(.title)
          .bold()
        Image(selectedProduct.image)
          .resizable()
          .scaledToFit()
          .clipShape(RoundedRectangle(cornerRadius: 15))
          .frame(minWidth: 100)
          .animation(.bouncy(duration: 0.5, extraBounce: 0.2), value: selectedProduct)
      }
      .frame(minWidth: 100)
      
    }
    .padding()
    Spacer()
  }
}

struct Product: Hashable, Identifiable {
  let id: UUID = UUID()
  let name: String
  
  var image: String {
    name.lowercased()
  }
  
  init(name: String) {
    self.name = name
  }
  
  static func products() -> [Product] {
    return [
      Product(name: "Chucks"),
      Product(name: "Sweater"),
      Product(name: "Shirt"),
      Product(name: "Jeans"),
      Product(name: "Sneakers")
    ]
  }
}

You can download the code from my GitHub repo

Photo Attributions

Photo by Mediamodifier on Unsplash
Photo by Mrushad Khombhadia on Unsplash
Photo by Waldemar on Unsplash
Photo by Théo rql on Unsplash
Photo by Huyen Nguy on Unsplash