Skip to content

Instantly share code, notes, and snippets.

@prafullakumar
Created April 14, 2020 15:14
Show Gist options
  • Save prafullakumar/bc32806d3881a72df608d4ef880f1a41 to your computer and use it in GitHub Desktop.
Save prafullakumar/bc32806d3881a72df608d4ef880f1a41 to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// newUI
//
// Created by prafull kumar on 3/4/20.
// Copyright © 2020 prafull kumar. All rights reserved.
//
import SwiftUI
struct ContentView: View {
@State private var name: String = ""
@State private var appointmentDate: String = ""
@State private var package: String = ""
@State private var phone: String = ""
let someFuturedate = Calendar.current.date(byAdding: .year, value: 20, to: Date()) ?? Date()
var body: some View {
NavigationView {
VStack(alignment: .leading) {
Group {
Text("Please Fill the form:").padding()
TextView(pickerType: .keyboard(type: .default), text: $name, placeholder: "Enter Name")
.frame(height: 40)
TextView(pickerType: .keyboard(type: .phonePad), text: $phone, placeholder: "Enter Phone Number")
.frame(height: 40)
TextView(pickerType: .datePicker(minDate: Date(), maxDate: someFuturedate), text: $appointmentDate, placeholder: "Select Date of Appointment")
.frame(height: 40)
TextView(pickerType: .customList(list: ["Premium","Economy","Free Demo"]), text: $package, placeholder: "Select Package")
.frame(height: 40)
}
Group {
Text("Your Input details:").padding()
Text("Name: \(name)").frame(height: 40)
Text("Appointment Date: \(appointmentDate)").frame(height: 40)
Text("Package: \(package)").frame(height: 40)
Text("Phone: \(phone)").frame(height: 40)
}
Spacer()
}
.padding()
.navigationBarTitle("Custom TextFields")
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
struct TextView: UIViewRepresentable {
enum PickerType {
case keyboard(type: UIKeyboardType)
case datePicker(minDate: Date, maxDate: Date)
case customList(list: [String])
}
var pickerType: TextView.PickerType
@Binding var text: String
let placeholder: String
func makeUIView(context: Context) -> UITextField {
let textField = UITextField()
textField.delegate = context.coordinator
textField.placeholder = placeholder
textField.frame.size.height = 40
textField.borderStyle = .roundedRect
textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
return textField
}
func updateUIView(_ uiView: UITextField, context: Context) {
switch pickerType {
case .datePicker:
uiView.text = text
case .customList:
uiView.text = text
default:
break
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(text: $text, pickerType: pickerType)
}
final class Coordinator: NSObject {
var text: Binding<String>
var pickerType: TextView.PickerType
init(text: Binding<String>, pickerType: TextView.PickerType) {
self.pickerType = pickerType
self.text = text
}
private func setPickerType(textField: UITextField) {
switch pickerType {
case .keyboard(let type):
textField.keyboardType = type
textField.inputView = nil
case .customList:
textField.inputView = getPicker()
case .datePicker(let minDate, let maxDate):
textField.inputView = getDatePicker(minDate: minDate, maxDate: maxDate)
}
textField.inputAccessoryView = getToolBar()
}
//Mark: custom Picker
private func getPicker() -> UIPickerView {
let picker = UIPickerView()
picker.backgroundColor = UIColor.systemBackground
picker.delegate = self
picker.dataSource = self
return picker
}
//Mark: date Picker
private func getDatePicker(minDate: Date, maxDate: Date) -> UIDatePicker {
let picker = UIDatePicker()
picker.datePickerMode = .date
picker.backgroundColor = UIColor.systemBackground
picker.maximumDate = maxDate
picker.minimumDate = minDate
picker.addTarget(self, action: #selector(handleDatePicker(sender:)), for: .valueChanged)
return picker
}
@objc func handleDatePicker(sender: UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy"
text.wrappedValue = dateFormatter.string(from: sender.date)
}
//Mark: Toolbar
private func getToolBar() -> UIToolbar {
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.backgroundColor = UIColor.systemBackground
toolBar.isTranslucent = true
toolBar.sizeToFit()
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: self, action: #selector(self.donePicker))
toolBar.setItems([spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
return toolBar
}
@objc func donePicker() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
}
extension TextView.Coordinator: UIPickerViewDataSource{
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch pickerType {
case .customList(let list):
return list.count
default:
return 0
}
}
}
extension TextView.Coordinator: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch pickerType {
case .customList(let list):
return list[row]
default:
return ""
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch pickerType {
case .customList(let list):
text.wrappedValue = list[row]
default:
break
}
}
}
extension TextView.Coordinator: UITextFieldDelegate {
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
setPickerType(textField: textField)
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
defer {
if let currentText = textField.text, let stringRange = Range(range, in: currentText) {
text.wrappedValue = currentText.replacingCharacters(in: stringRange, with: string)
}
}
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
donePicker()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment