Merge branch 'feature/datePicker' into 'develop'

DatePicker merge

See merge request BPHV_MIPS/vds_ios_sample!65
This commit is contained in:
Bruce, Matt R 2024-05-14 23:36:37 +00:00
commit 98e277a9cc
8 changed files with 768 additions and 23 deletions

View File

@ -35,6 +35,7 @@
1808BEBE2BA4479500129230 /* CarouselScrollbarViewConttroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1808BEBD2BA4479500129230 /* CarouselScrollbarViewConttroller.swift */; };
1832AC5B2BA1347B008AE476 /* BreadcrumbsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1832AC5A2BA1347B008AE476 /* BreadcrumbsViewController.swift */; };
186D13CD2BBA990800986B53 /* DropdownSelectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 186D13CC2BBA990800986B53 /* DropdownSelectViewController.swift */; };
18A3F1302BD9332500498E4A /* CalendarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A3F12F2BD9332500498E4A /* CalendarViewController.swift */; };
445BA07A29C088470036A7C5 /* NotificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07929C088470036A7C5 /* NotificationViewController.swift */; };
44604AD929CE1CF900E62B51 /* LineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD829CE1CF900E62B51 /* LineViewController.swift */; };
5FC35BE928D5235A004EBEAC /* ButtonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE828D5235A004EBEAC /* ButtonViewController.swift */; };
@ -43,6 +44,7 @@
EA0D1C312A673F3500E5C127 /* RadioButtonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C302A673F3500E5C127 /* RadioButtonViewController.swift */; };
EA0D1C332A673FD400E5C127 /* RadioButtonItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C322A673FD400E5C127 /* RadioButtonItemViewController.swift */; };
EA0FC2C12912DC5500DF80B4 /* TextLinkCaretViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0FC2C02912DC5500DF80B4 /* TextLinkCaretViewController.swift */; };
EA1758462BC8893700A5C0D9 /* DatePickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1758452BC8893700A5C0D9 /* DatePickerViewController.swift */; };
EA21C5D82B600E4200CFC139 /* VDSTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA21C5D72B600E4200CFC139 /* VDSTokens.xcframework */; };
EA21C5D92B600E4200CFC139 /* VDSTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EA21C5D72B600E4200CFC139 /* VDSTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
EA297A682A02F5320031ED56 /* TableViewTestController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA297A672A02F5320031ED56 /* TableViewTestController.swift */; };
@ -129,6 +131,7 @@
1808BEBD2BA4479500129230 /* CarouselScrollbarViewConttroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselScrollbarViewConttroller.swift; sourceTree = "<group>"; };
1832AC5A2BA1347B008AE476 /* BreadcrumbsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbsViewController.swift; sourceTree = "<group>"; };
186D13CC2BBA990800986B53 /* DropdownSelectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropdownSelectViewController.swift; sourceTree = "<group>"; };
18A3F12F2BD9332500498E4A /* CalendarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarViewController.swift; sourceTree = "<group>"; };
445BA07929C088470036A7C5 /* NotificationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationViewController.swift; sourceTree = "<group>"; };
44604AD829CE1CF900E62B51 /* LineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineViewController.swift; sourceTree = "<group>"; };
5FC35BE828D5235A004EBEAC /* ButtonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonViewController.swift; sourceTree = "<group>"; };
@ -137,6 +140,7 @@
EA0D1C302A673F3500E5C127 /* RadioButtonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonViewController.swift; sourceTree = "<group>"; };
EA0D1C322A673FD400E5C127 /* RadioButtonItemViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonItemViewController.swift; sourceTree = "<group>"; };
EA0FC2C02912DC5500DF80B4 /* TextLinkCaretViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLinkCaretViewController.swift; sourceTree = "<group>"; };
EA1758452BC8893700A5C0D9 /* DatePickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerViewController.swift; sourceTree = "<group>"; };
EA21C5D72B600E4200CFC139 /* VDSTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTokens.xcframework; path = SharedFrameworks/VDSTokens.xcframework; sourceTree = "<group>"; };
EA297A672A02F5320031ED56 /* TableViewTestController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewTestController.swift; sourceTree = "<group>"; };
EA3C3B99289966EF000CA526 /* VDSSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VDSSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -317,10 +321,12 @@
EAB5FEEE2927E28400998C17 /* ButtonGroupViewController.swift */,
EA81410D2A0ED8DC004F60D2 /* ButtonIconViewController.swift */,
5FC35BE828D5235A004EBEAC /* ButtonViewController.swift */,
18A3F12F2BD9332500498E4A /* CalendarViewController.swift */,
1808BEBD2BA4479500129230 /* CarouselScrollbarViewConttroller.swift */,
EA89204D28B67332006B9984 /* CheckBoxGroupViewController.swift */,
EAF7F09B2899B92400B287F5 /* CheckboxItemViewController.swift */,
EA0D1C2E2A66CFE900E5C127 /* CheckboxViewController.swift */,
EA1758452BC8893700A5C0D9 /* DatePickerViewController.swift */,
186D13CC2BBA990800986B53 /* DropdownSelectViewController.swift */,
EA985C00296CC21C00F2FF2E /* IconViewController.swift */,
EAA5EEAC28EB6924003B3210 /* InputFieldViewController.swift */,
@ -515,6 +521,7 @@
EA3C3BB428996775000CA526 /* PickerBase.swift in Sources */,
EAB2376C29E9E74900AABE9A /* TrailingTooltipLabelViewController.swift in Sources */,
EAB1D2C928AAAA1D00DAE764 /* BaseViewController.swift in Sources */,
EA1758462BC8893700A5C0D9 /* DatePickerViewController.swift in Sources */,
EAD062AD2A3B86950015965D /* BadgeIndicatorViewController.swift in Sources */,
EA5E305C295111050082B959 /* TileletViewController.swift in Sources */,
EAD062A32A3913920015965D /* DropShawdowViewController.swift in Sources */,
@ -529,6 +536,7 @@
71B23C312B921D740027F7D9 /* PaginationViewController.swift in Sources */,
EAF7F09C2899B92400B287F5 /* CheckboxItemViewController.swift in Sources */,
EA0D1C2F2A66CFE900E5C127 /* CheckboxViewController.swift in Sources */,
18A3F1302BD9332500498E4A /* CalendarViewController.swift in Sources */,
EA596ABA2A16B2ED00300C4B /* TabsViewController.swift in Sources */,
EA89204E28B67332006B9984 /* CheckBoxGroupViewController.swift in Sources */,
EAA5EEAD28EB6924003B3210 /* InputFieldViewController.swift in Sources */,
@ -692,7 +700,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62;
CURRENT_PROJECT_VERSION = 63;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = FCMA4QKS77;
GENERATE_INFOPLIST_FILE = YES;
@ -727,7 +735,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 62;
CURRENT_PROJECT_VERSION = 63;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = FCMA4QKS77;
GENERATE_INFOPLIST_FILE = YES;

File diff suppressed because one or more lines are too long

View File

@ -134,8 +134,15 @@ public class PickerSelectorView<EnumType: RawRepresentable>: UIStackView, Picker
}
private func title(for row: Int) -> String {
guard let item = items[row].rawValue as? String else { return "" }
return item
let item = items[row]
if let item = item as? CustomStringConvertible {
return item.description
} else if let raw = item.rawValue as? String {
return raw
} else {
return ""
}
}
}

View File

@ -1,15 +0,0 @@
{
"images" : [
{
"filename" : "external-link.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -1 +0,0 @@
<svg id="f5a11f6b-f49f-40e8-9fef-b62ba7c1147d" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.6 21.6"><path d="M19.8,1.8V8.2H18.68V3.72L12.56,9.84l-.8-.8,6.12-6.11H13.4V1.8ZM15.3,18.68H2.93V6.3H12.8l1-1.12H1.8V19.8H16.43V7.8l-1.13,1Z"/></svg>

Before

Width:  |  Height:  |  Size: 266 B

View File

@ -0,0 +1,305 @@
//
// CalendarViewController.swift
// VDSSample
//
// Created by Kanamarlapudi, Vasavi on 19/04/24.
//
import Foundation
import UIKit
import VDS
import Combine
import VDSTokens
class CalendarViewController: BaseViewController<CalendarBase> {
let label = Label()
var containerBorderSwitch = Toggle()
var hideCurrentDateIndicatorSwitch = Toggle()
var transparentBgSwitch = Toggle()
var indicatorOneSwitch = Toggle()
var indicatorTwoSwitch = Toggle()
var indicatorThreeSwitch = Toggle()
var clearActiveDatesSwitch = Toggle()
var clearInactiveDatesSwitch = Toggle()
var activeDatesField = TextField()
var inactiveDatesField = TextField()
var legendOneField = TextField()
var legendTwoField = TextField()
var legendThreeField = TextField()
private var minDatePicker: UIDatePicker = UIDatePicker()
private var maxDatePicker: UIDatePicker = UIDatePicker()
private var indicatorOnePicker: UIDatePicker = UIDatePicker()
private var indicatorTwoPicker: UIDatePicker = UIDatePicker()
private var indicatorThreePicker: UIDatePicker = UIDatePicker()
private var activeDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
private var inactiveDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
var indicators: [CalendarBase.CalendarIndicatorModel] = []
let indicatorOnePickerTag = 1
let indicatorTwoPickerTag = 2
let indicatorThreePickerTag = 3
let minDatePickerTag = 4
let maxDatePickerTag = 5
let activeDatePickerTag = 6
let inactiveDatePickerTag = 7
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: component)
component.minDate = Date().startOfMonth
component.maxDate = Date().endOfMonth
component.onChange = { [weak self] control in
self?.label.text = DateFormatter.localizedString(from: control.selectedDate, dateStyle: .short, timeStyle: .none)
}
minDatePicker.date = component.minDate
maxDatePicker.date = component.maxDate
setupPicker()
setupModel()
}
override func setupForm() {
super.setupForm()
configurePicker(indicatorOnePicker)
indicatorOnePicker.tag = indicatorOnePickerTag
configurePicker(indicatorTwoPicker)
indicatorTwoPicker.tag = indicatorTwoPickerTag
configurePicker(indicatorThreePicker)
indicatorThreePicker.tag = indicatorThreePickerTag
configurePicker(minDatePicker)
minDatePicker.tag = minDatePickerTag
configurePicker(maxDatePicker)
maxDatePicker.tag = maxDatePickerTag
configurePicker(activeDatePicker)
activeDatePicker.tag = activeDatePickerTag
configurePicker(inactiveDatePicker)
inactiveDatePicker.tag = inactiveDatePickerTag
indicators = [
.init(label: "Due Date", date: indicatorOnePicker.date),
.init(label: "Auto Pay", date: indicatorTwoPicker.date),
.init(label: "Scheduled", date: indicatorThreePicker.date)
]
//add form rows
addFormRow(label: "onChange", view: label)
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Hide Container Border", view: containerBorderSwitch)
addFormRow(label: "Hide Current Date Indicator", view: hideCurrentDateIndicatorSwitch)
addFormRow(label: "Min Date", view: minDatePicker)
addFormRow(label: "Max Date", view: maxDatePicker)
addFormRow(label: "Transparent Background", view: transparentBgSwitch)
addFormRow(label: "Active Dates", view: activeDatesField)
addFormRow(label: "Select ActiveDate", view: activeDatePicker)
addFormRow(label: "Clear Active Dates", view: clearActiveDatesSwitch)
addFormRow(label: "Inactive Dates", view: inactiveDatesField)
addFormRow(label: "Select InActiveDate", view: inactiveDatePicker)
addFormRow(label: "Clear Inactive Dates", view: clearInactiveDatesSwitch)
addFormRow(label: "Indicator One", view: indicatorOneSwitch)
addFormRow(label: "Indicator Two", view: indicatorTwoSwitch)
addFormRow(label: "Indicator Three", view: indicatorThreeSwitch)
addFormRow(label: "Legend One", view: legendOneField)
addFormRow(label: "Legend Two", view: legendTwoField)
addFormRow(label: "Legend Three", view: legendThreeField)
addFormRow(label: "Indicator One Date", view: indicatorOnePicker)
addFormRow(label: "Indicator Two Date", view: indicatorTwoPicker)
addFormRow(label: "Indicator Three Date", view: indicatorThreePicker)
activeDatesField.isUserInteractionEnabled = false
inactiveDatesField.isUserInteractionEnabled = false
activeDatesField.isEnabled = false
inactiveDatesField.isEnabled = false
containerBorderSwitch.onChange = { [weak self] sender in
guard let self else { return }
component.hideContainerBorder = sender.isOn
}
hideCurrentDateIndicatorSwitch.onChange = { [weak self] sender in
guard let self else { return }
component.hideCurrentDateIndicator = sender.isOn
}
transparentBgSwitch.onChange = { [weak self] sender in
guard let self else { return }
component.transparentBackground = sender.isOn
}
clearActiveDatesSwitch.onChange = { [weak self] sender in
guard let self else { return }
if sender.isOn {
activeDatesField.text = ""
component.activeDates = []
}
}
clearInactiveDatesSwitch.onChange = { [weak self] sender in
guard let self else { return }
if sender.isOn {
inactiveDatesField.text = ""
component.inactiveDates = []
}
}
legendOneField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorOnePicker.date, index: 0)
}.store(in: &subscribers)
legendTwoField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorTwoPicker.date, index: 1)
}.store(in: &subscribers)
legendThreeField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorThreePicker.date, index: 2)
}.store(in: &subscribers)
indicatorOneSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
component.indicators.removeAll()
} else {
self.setIndicatorsData()
}
}
indicatorTwoSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if component.indicators.count > 2 {
component.indicators.removeLast()
component.indicators.removeLast()
} else if component.indicators.count == 2 {
component.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
}
indicatorThreeSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if component.indicators.count > 2 {
component.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
}
}
func setupPicker(){
surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.surface = item
self?.contentTopView.backgroundColor = item.color
}
}
func setupModel() {
let calendar = Calendar.current
let indicatorDate = calendar.startOfDay(for: calendar.date(byAdding: .day, value: 1, to: Date())!)
component.indicators = indicators
legendOneField.text = "Due Date"
legendTwoField.text = "Auto Pay"
legendThreeField.text = "Scheduled"
indicatorOneSwitch.isOn = true
indicatorTwoSwitch.isOn = true
indicatorThreeSwitch.isOn = true
hideCurrentDateIndicatorSwitch.isOn = false
indicatorOnePicker.date = indicatorDate
indicatorTwoPicker.date = indicatorDate
indicatorThreePicker.date = indicatorDate
updateIndicatorData(label: legendOneField.text ?? "", date: indicatorOnePicker.date, index: 0)
updateIndicatorData(label: legendTwoField.text ?? "", date: indicatorTwoPicker.date, index: 1)
updateIndicatorData(label: legendThreeField.text ?? "", date: indicatorThreePicker.date, index: 2)
}
func updateIndicatorData(label: String = "", date: Date?, index:Int) {
indicators[index].label = label
indicators[index].date = date ?? Date()
component.indicators = indicators
}
func setIndicatorsData() {
if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && indicatorThreeSwitch.isOn {
component.indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
.init(label: self.legendThreeField.text ?? "", date: indicatorThreePicker.date)
]
} else if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && !indicatorThreeSwitch.isOn {
component.indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
]
} else if indicatorOneSwitch.isOn && !indicatorTwoSwitch.isOn {
component.indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
]
}
}
func configurePicker(_ sender:UIDatePicker) {
// Set some of UIDatePicker properties
sender.timeZone = NSTimeZone.local
sender.backgroundColor = UIColor.white
// Add an event to call onDidChangeDate function when value is changed.
sender.addTarget(self, action: #selector(self.datePickerValueChanged(_:)), for: .valueChanged)
}
@objc func datePickerValueChanged(_ sender: UIDatePicker){
switch sender.tag {
case indicatorOnePickerTag:
updateIndicatorData(label: legendOneField.text ?? "", date: sender.date, index: 0)
case indicatorTwoPickerTag:
updateIndicatorData(label: legendTwoField.text ?? "", date: sender.date, index: 1)
case indicatorThreePickerTag:
updateIndicatorData(label: legendThreeField.text ?? "", date: sender.date, index: 2)
case minDatePickerTag:
component.minDate = sender.date
case maxDatePickerTag:
component.maxDate = sender.date
case activeDatePickerTag:
component.activeDates.append(sender.date)
var text = activeDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearActiveDatesSwitch.isOn = false
activeDatesField.text = text
case inactiveDatePickerTag:
component.inactiveDates.append(sender.date)
var text = inactiveDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearInactiveDatesSwitch.isOn = false
inactiveDatesField.text = text
default: break
}
}
func getSelectedDate(with date:Date) -> String {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let day: String = dateFormatter.string(from: date)
return day
}
}

View File

@ -0,0 +1,441 @@
//
// DatePickerViewController.swift
// VDSSample
//
// Created by Matt Bruce on 4/11/24.
//
import Foundation
import VDS
import UIKit
class DatePickerViewController: BaseViewController<DatePicker> {
// Datepicker
var label = Label()
var disabledSwitch = Toggle()
var requiredSwitch = Toggle()
var labelTextField = TextField()
var errorTextField = TextField()
var helperTextField = TextField()
var inlineLabelSwitch = Toggle()
var readonlySwitch = Toggle()
var transparentBgSwitch = Toggle()
var errorSwitch = Toggle()
var tooltipTitleTextField = TextField()
var tooltipContentTextField = TextField()
lazy var dateFormatPickerSelectorView = {
PickerSelectorView(title: "shortNumeric",
picker: self.picker,
items: DatePicker.DateFormat.allCases )
}()
// Calendar
//props
var indicators: [CalendarBase.CalendarIndicatorModel] = []
var activeDates: [Date] = []
var inactiveDates: [Date] = []
var minDate: Date = Date().startOfMonth
var maxDate: Date = Date().endOfMonth
//form
var containerBorderSwitch = Toggle()
var hideCurrentDateIndicatorSwitch = Toggle()
var indicatorOneSwitch = Toggle()
var indicatorTwoSwitch = Toggle()
var indicatorThreeSwitch = Toggle()
var clearActiveDatesSwitch = Toggle()
var clearInactiveDatesSwitch = Toggle()
var activeDatesField = TextField()
var inactiveDatesField = TextField()
var legendOneField = TextField()
var legendTwoField = TextField()
var legendThreeField = TextField()
private var minDatePicker: UIDatePicker = UIDatePicker()
private var maxDatePicker: UIDatePicker = UIDatePicker()
private var indicatorOnePicker: UIDatePicker = UIDatePicker()
private var indicatorTwoPicker: UIDatePicker = UIDatePicker()
private var indicatorThreePicker: UIDatePicker = UIDatePicker()
private var activeDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
private var inactiveDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
let indicatorOnePickerTag = 1
let indicatorTwoPickerTag = 2
let indicatorThreePickerTag = 3
let minDatePickerTag = 4
let maxDatePickerTag = 5
let activeDatePickerTag = 6
let inactiveDatePickerTag = 7
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: component)
setupModel()
setupPicker()
setupCalendar()
}
override func setupForm(){
addFormRow(label: "onChange", view: label)
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Disabled", view: disabledSwitch)
addFormRow(label: "Required", view: requiredSwitch)
addFormRow(label: "Date Format", view: dateFormatPickerSelectorView)
addFormRow(label: "Label Text", view: labelTextField)
addFormRow(label: "Helper Text", view: helperTextField)
addFormRow(label: "Readonly", view: readonlySwitch)
addFormRow(label: "Transparent Background", view: transparentBgSwitch)
addFormRow(label: "Error", view: .makeWrapper(for: errorSwitch))
addFormRow(label: "Error Text", view: errorTextField)
addFormRow(label: "ToolTip Title", view: tooltipTitleTextField)
addFormRow(label: "ToolTip Content", view: tooltipContentTextField)
append(section: getCalendarSection())
disabledSwitch.onChange = { [weak self] sender in
self?.component.isEnabled = !sender.isOn
}
requiredSwitch.onChange = { [weak self] sender in
self?.component.isRequired = sender.isOn
}
readonlySwitch.onChange = { [weak self] sender in
self?.component.isReadOnly = sender.isOn
}
transparentBgSwitch.onChange = { [weak self] sender in
self?.component.transparentBackground = sender.isOn
}
errorSwitch
.publisher(for: .valueChanged)
.sink { [weak self] sender in
guard let self else { return }
component.showError = sender.isOn
if component.showError != sender.isOn {
self.errorSwitch.isOn = self.component.showError
}
}.store(in: &subscribers)
labelTextField
.textPublisher
.sink { [weak self] text in
self?.component.labelText = text
}.store(in: &subscribers)
helperTextField
.textPublisher
.sink { [weak self] text in
self?.component.helperText = text
}.store(in: &subscribers)
errorTextField
.textPublisher
.sink { [weak self] text in
self?.component.errorText = text
}.store(in: &subscribers)
tooltipTitleTextField
.textPublisher
.sink { [weak self] text in
self?.updateTooltip()
}.store(in: &subscribers)
tooltipContentTextField
.textPublisher
.sink { [weak self] text in
self?.updateTooltip()
}.store(in: &subscribers)
}
func setupModel() {
component.selectedDate = Calendar.current.date(byAdding: .day, value: -5, to: Date())
component.labelText = "Date"
component.helperText = "Pick a date for your needs."
component.errorText = "Enter a date."
component.tooltipModel = .init(title: "Check your date.", content:"Here is the content for your date component")
component.onChange = { [weak self] control in
self?.label.text = DateFormatter.localizedString(from: control.selectedDate!, dateStyle: .short, timeStyle: .none)
}
//setup UI
disabledSwitch.isOn = !component.isEnabled
requiredSwitch.isOn = component.isRequired
surfacePickerSelectorView.text = component.surface.rawValue
labelTextField.text = component.labelText
helperTextField.text = component.helperText
readonlySwitch.isOn = false
transparentBgSwitch.isOn = false
errorSwitch.isOn = component.showError
errorTextField.text = component.errorText
tooltipTitleTextField.text = component.tooltipModel?.title
tooltipContentTextField.text = component.tooltipModel?.content
}
func setupPicker() {
surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.surface = item
self?.contentTopView.backgroundColor = item.color
}
dateFormatPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.dateFormat = item
}
}
func updateTooltip() {
let title = tooltipTitleTextField.text ?? ""
let content = tooltipContentTextField.text ?? ""
component.tooltipModel = !title.isEmpty || !content.isEmpty ? .init(title: title,
content: content) : nil
}
}
extension DatePickerViewController {
func getCalendarSection() -> FormSection {
let section = FormSection()
section.title = "Calendar Options"
section.addFormRow(label: "Hide Container Border", view: containerBorderSwitch)
section.addFormRow(label: "Hide Current Date Indicator", view: hideCurrentDateIndicatorSwitch)
section.addFormRow(label: "Min Date", view: minDatePicker)
section.addFormRow(label: "Max Date", view: maxDatePicker)
section.addFormRow(label: "Active Dates", view: activeDatesField)
section.addFormRow(label: "Select ActiveDate", view: activeDatePicker)
section.addFormRow(label: "Clear Active Dates", view: clearActiveDatesSwitch)
section.addFormRow(label: "Inactive Dates", view: inactiveDatesField)
section.addFormRow(label: "Select InActiveDate", view: inactiveDatePicker)
section.addFormRow(label: "Clear Inactive Dates", view: clearInactiveDatesSwitch)
section.addFormRow(label: "Indicator One", view: indicatorOneSwitch)
section.addFormRow(label: "Indicator Two", view: indicatorTwoSwitch)
section.addFormRow(label: "Indicator Three", view: indicatorThreeSwitch)
section.addFormRow(label: "Legend One", view: legendOneField)
section.addFormRow(label: "Legend Two", view: legendTwoField)
section.addFormRow(label: "Legend Three", view: legendThreeField)
section.addFormRow(label: "Indicator One Date", view: indicatorOnePicker)
section.addFormRow(label: "Indicator Two Date", view: indicatorTwoPicker)
section.addFormRow(label: "Indicator Three Date", view: indicatorThreePicker)
containerBorderSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
hideCurrentDateIndicatorSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
clearActiveDatesSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
clearInactiveDatesSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
legendOneField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorOnePicker.date, index: 0)
}.store(in: &subscribers)
legendTwoField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorTwoPicker.date, index: 1)
}.store(in: &subscribers)
legendThreeField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorThreePicker.date, index: 2)
}.store(in: &subscribers)
indicatorOneSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
self.indicators.removeAll()
} else {
self.setIndicatorsData()
}
self.updateCalendarModel()
}
indicatorTwoSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if self.indicators.count > 2 {
self.indicators.removeLast()
self.indicators.removeLast()
} else if self.indicators.count == 2 {
self.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
self.updateCalendarModel()
}
indicatorThreeSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if self.indicators.count > 2 {
self.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
self.updateCalendarModel()
}
return section
}
func updateCalendarModel() {
component.calendarModel = .init(surface: component.surface,
hideContainerBorder: containerBorderSwitch.isOn,
hideCurrentDateIndicator: hideCurrentDateIndicatorSwitch.isOn,
activeDates: activeDates,
inactiveDates: inactiveDates,
minDate: minDate,
maxDate: maxDate,
indicators: indicators)
}
func setupCalendar() {
configurePicker(indicatorOnePicker)
indicatorOnePicker.tag = indicatorOnePickerTag
configurePicker(indicatorTwoPicker)
indicatorTwoPicker.tag = indicatorTwoPickerTag
configurePicker(indicatorThreePicker)
indicatorThreePicker.tag = indicatorThreePickerTag
configurePicker(minDatePicker)
minDatePicker.tag = minDatePickerTag
configurePicker(maxDatePicker)
maxDatePicker.tag = maxDatePickerTag
configurePicker(activeDatePicker)
activeDatePicker.tag = activeDatePickerTag
configurePicker(inactiveDatePicker)
inactiveDatePicker.tag = inactiveDatePickerTag
indicators = [
.init(label: "Due Date", date: indicatorOnePicker.date),
.init(label: "Auto Pay", date: indicatorTwoPicker.date),
.init(label: "Scheduled", date: indicatorThreePicker.date)
]
let calendar = Calendar.current
let indicatorDate = calendar.startOfDay(for: calendar.date(byAdding: .day, value: 1, to: Date())!)
legendOneField.text = "Due Date"
legendTwoField.text = "Auto Pay"
legendThreeField.text = "Scheduled"
indicatorOneSwitch.isOn = true
indicatorTwoSwitch.isOn = true
indicatorThreeSwitch.isOn = true
hideCurrentDateIndicatorSwitch.isOn = false
indicatorOnePicker.date = indicatorDate
indicatorTwoPicker.date = indicatorDate
indicatorThreePicker.date = indicatorDate
updateIndicatorData(label: legendOneField.text ?? "", date: indicatorOnePicker.date, index: 0)
updateIndicatorData(label: legendTwoField.text ?? "", date: indicatorTwoPicker.date, index: 1)
updateIndicatorData(label: legendThreeField.text ?? "", date: indicatorThreePicker.date, index: 2)
activeDatesField.isUserInteractionEnabled = false
inactiveDatesField.isUserInteractionEnabled = false
activeDatesField.isEnabled = false
inactiveDatesField.isEnabled = false
minDatePicker.date = minDate
maxDatePicker.date = maxDate
updateCalendarModel()
}
func updateIndicatorData(label: String = "", date: Date?, index:Int) {
indicators[index].label = label
indicators[index].date = date ?? Date()
updateCalendarModel()
}
func setIndicatorsData() {
if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && indicatorThreeSwitch.isOn {
indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
.init(label: self.legendThreeField.text ?? "", date: indicatorThreePicker.date)
]
} else if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && !indicatorThreeSwitch.isOn {
indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
]
} else if indicatorOneSwitch.isOn && !indicatorTwoSwitch.isOn {
indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
]
}
}
func configurePicker(_ sender:UIDatePicker) {
// Set some of UIDatePicker properties
sender.timeZone = NSTimeZone.local
sender.backgroundColor = UIColor.white
// Add an event to call onDidChangeDate function when value is changed.
sender.addTarget(self, action: #selector(self.datePickerValueChanged(_:)), for: .valueChanged)
}
@objc func datePickerValueChanged(_ sender: UIDatePicker){
switch sender.tag {
case indicatorOnePickerTag:
updateIndicatorData(label: legendOneField.text ?? "", date: sender.date, index: 0)
case indicatorTwoPickerTag:
updateIndicatorData(label: legendTwoField.text ?? "", date: sender.date, index: 1)
case indicatorThreePickerTag:
updateIndicatorData(label: legendThreeField.text ?? "", date: sender.date, index: 2)
case minDatePickerTag:
minDate = sender.date
case maxDatePickerTag:
maxDate = sender.date
case activeDatePickerTag:
activeDates.append(sender.date)
var text = activeDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearActiveDatesSwitch.isOn = false
activeDatesField.text = text
case inactiveDatePickerTag:
inactiveDates.append(sender.date)
var text = inactiveDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearInactiveDatesSwitch.isOn = false
inactiveDatesField.text = text
default: break
}
}
func getSelectedDate(with date:Date) -> String {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let day: String = dateFormatter.string(from: date)
return day
}
}

View File

@ -74,10 +74,12 @@ class MenuViewController: UITableViewController, TooltipLaunchable {
MenuComponent(title: "Button", completed: true, viewController: ButtonViewController.self),
MenuComponent(title: "ButtonGroup", completed: true, viewController: ButtonGroupViewController.self),
MenuComponent(title: "ButtonIcon", completed: true, viewController: ButtonIconViewController.self),
MenuComponent(title: "Calendar", completed: true, viewController: CalendarViewController.self),
MenuComponent(title: "Carousel Scrollbar", completed: true, viewController: CarouselScrollbarViewConttroller.self),
MenuComponent(title: "Checkbox", completed: true, viewController: CheckboxViewController.self),
MenuComponent(title: "CheckboxItem", completed: true, viewController: CheckboxItemViewController.self),
MenuComponent(title: "CheckboxGroup", completed: true, viewController: CheckboxGroupViewController.self),
MenuComponent(title: "DatePicker", completed: true, viewController: DatePickerViewController.self),
MenuComponent(title: "DropdownSelect", completed: true, viewController: DropdownSelectViewController.self),
MenuComponent(title: "Icon", completed: true, viewController: IconViewController.self),
MenuComponent(title: "InputField", completed: true, viewController: InputFieldViewController.self),