Created
April 14, 2020 15:14
-
-
Save prafullakumar/bc32806d3881a72df608d4ef880f1a41 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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