Digital ACT-191 ONEAPP-7958 story: handling days of month based on min, max date and active, inactive dates selected.

This commit is contained in:
vasavk 2024-05-09 13:38:02 +05:30
parent 450dd1aae8
commit 4b5c4a28b2
2 changed files with 102 additions and 33 deletions

View File

@ -39,7 +39,7 @@ open class CalendarBase: View {
open var hideCurrentDateIndicator: Bool = false { didSet { setNeedsUpdate() } }
/// Enable specific days. Pass an array of string value in date format e.g. ['07/21/2024', '07/24/2024', 07/28/2024'].
/// All other dates will be inactive
/// All other dates will be inactive.
open var activeDates: [Date] = [] { didSet { setNeedsUpdate() } }
/// Disable specific days. Pass an array of string value in date format e.g. ['07/21/2024', '07/24/2024', 07/28/2024'].
@ -112,12 +112,13 @@ open class CalendarBase: View {
internal var backgroundColorConfiguration = SurfaceColorConfiguration(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark)
//--------------------------------------------------
// MARK: - Lifecycle
// MARK: - Overrides
//--------------------------------------------------
open override func initialSetup() {
super.initialSetup()
}
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
open override func setup() {
super.setup()
isAccessibilityElement = false
@ -171,6 +172,7 @@ open class CalendarBase: View {
super.layoutSubviews()
}
/// Resets to default settings.
open override func reset() {
super.reset()
}
@ -283,6 +285,7 @@ extension CalendarBase: UICollectionViewDelegate, UICollectionViewDataSource, UI
onChangeSelectedDate?(selectedItem)
selectedDate = self.dates[indexPath.row]
displayDate = selectedDate
var reloadIndexPaths = [indexPath]
// If an cell is already selected, then it needs to be deselected.

View File

@ -68,6 +68,10 @@ final class CalendarDateCollectionViewCell: UICollectionViewCell {
setUp()
}
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
/// Configuring the cell with default setup
private func setUp() {
isAccessibilityElement = false
@ -95,37 +99,20 @@ final class CalendarDateCollectionViewCell: UICollectionViewCell {
/// Updating UI based on selected date, modified indicators data along with surface
/// Enable/disable cell based on min date, max date, active dates, inactive dates
func update(with surface: Surface, indicators: [CalendarBase.CalendarIndicatorModel], text: String, indicatorCount: Int, selectedDate: Date, displayDate: Date, hideDate: Bool, minDate: Date, maxDate: Date, activeDates: [Date], inactiveDates: [Date]) {
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
numberLabel.surface = surface
numberLabel.text = text
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
// enable/disable cells based on min date, max date.
if let day:Int = Int(numberLabel.text), day < minDate.dayInt || day > maxDate.dayInt {
numberLabel.isEnabled = false
numberLabel.textColor = disabledTextColorConfiguration.getColor(surface)
layer.backgroundColor = disabledBackgroundColor.getColor(surface).cgColor
} else {
numberLabel.isEnabled = false
// handing active dates
if activeDates.count > 0 && inactiveDates.count == 0 {
for x in (0...(activeDates.count-1)) {
if let day:Int = Int(numberLabel.text), day == activeDates[x].dayInt {
numberLabel.isEnabled = true
}
}
} else {
numberLabel.isEnabled = true
}
}
// enable/disable cells based on min date, max date and active/inactive dates
self.updateLabel(with:surface, displayDate: displayDate, minDate: minDate, maxDate: maxDate, activeDates: activeDates, inactiveDates: inactiveDates)
// handling inactive dates
if inactiveDates.count > 0 {
for x in (0...(inactiveDates.count-1)) {
if (activeDates[x].monthInt == displayDate.monthInt) && (activeDates[x].yearInt == displayDate.yearInt) {
if (inactiveDates[x].monthInt == displayDate.monthInt) && (inactiveDates[x].yearInt == displayDate.yearInt) {
if let day:Int = Int(numberLabel.text), day == inactiveDates[x].dayInt {
numberLabel.isEnabled = false
numberLabel.textColor = disabledTextColorConfiguration.getColor(surface)
layer.backgroundColor = disabledBackgroundColor.getColor(surface).cgColor
disableLabel(with: surface)
}
}
}
@ -145,24 +132,103 @@ final class CalendarDateCollectionViewCell: UICollectionViewCell {
// add indicators
if indicatorCount > 0 {
for x in (0...(indicators.count-1)) {
if (self.numberLabel.text == self.getDay(with: indicators[x].date)) {
let color = (numberLabel.text == self.getDay(with: selectedDate)) ? selectedCellIndicatorColorConfiguration.getColor(surface) : unselectedCellIndicatorColorConfiguration.getColor(surface)
addIndicator(with: color, surface: surface, clearFullCircle: (x == 1), drawSemiCircle: (x == 2))
// irrespective of month and year, if it needs to show indicators on every month - comment below first if condition
if (indicators[x].date.monthInt == displayDate.monthInt) && (indicators[x].date.yearInt == displayDate.yearInt) {
if (self.numberLabel.text == self.getDay(with: indicators[x].date)) {
let color = (numberLabel.text == self.getDay(with: selectedDate)) ? selectedCellIndicatorColorConfiguration.getColor(surface) : unselectedCellIndicatorColorConfiguration.getColor(surface)
addIndicator(with: color, surface: surface, clearFullCircle: (x == 1), drawSemiCircle: (x == 2))
}
}
}
}
// update text style for current date
if (numberLabel.text == self.getDay(with: currentDate)) && (currentDate.monthInt == displayDate.monthInt) {
if (numberLabel.text == self.getDay(with: currentDate)) && (currentDate.monthInt == displayDate.monthInt) && (currentDate.yearInt == displayDate.yearInt) {
numberLabel.textStyle = hideDate ? .bodySmall : .boldBodySmall
} else {
numberLabel.textStyle = .bodySmall
}
}
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
func disableLabel(with surface: Surface) {
numberLabel.isEnabled = false
numberLabel.textColor = disabledTextColorConfiguration.getColor(surface)
layer.backgroundColor = disabledBackgroundColor.getColor(surface).cgColor
}
func showActiveDates(with displayDate: Date, activeDates: [Date], inactiveDates: [Date]) {
for x in (0...(activeDates.count-1)) {
if (activeDates[x].monthInt == displayDate.monthInt) && (activeDates[x].yearInt == displayDate.yearInt ) {
if let day:Int = Int(numberLabel.text), day == activeDates[x].dayInt {
numberLabel.isEnabled = true
}
}
}
}
// handing active dates if exist, else enable numberLabel to display day
func handleActiveDates(with displayDate: Date, activeDates: [Date], inactiveDates: [Date]) {
if activeDates.count > 0 && inactiveDates.count == 0 {
showActiveDates(with: displayDate, activeDates: activeDates, inactiveDates: inactiveDates)
} else {
numberLabel.isEnabled = true
}
}
// enable all days if no active dates, handing active dates if exist
func enableAllDaysAndCheckActiveDates(with surface:Surface, displayDate: Date, activeDates: [Date], inactiveDates: [Date]) {
if activeDates.count > 0 && inactiveDates.count == 0 {
disableLabel(with: surface)
showActiveDates(with: displayDate, activeDates: activeDates, inactiveDates: inactiveDates)
} else {
numberLabel.isEnabled = true
}
}
// enable/disable cells based on min date, max date and active/inactive dates
func updateLabel(with surface: Surface, displayDate: Date, minDate: Date, maxDate: Date, activeDates: [Date], inactiveDates: [Date]) {
if (minDate.yearInt == displayDate.yearInt) || (maxDate.yearInt == displayDate.yearInt) {
if (minDate.monthInt == displayDate.monthInt) && (maxDate.monthInt == displayDate.monthInt) {
// validate days to enable/disable
if let day:Int = Int(numberLabel.text), day < minDate.dayInt || day > maxDate.dayInt {
disableLabel(with: surface)
} else {
numberLabel.isEnabled = false
handleActiveDates(with: displayDate, activeDates: activeDates, inactiveDates: inactiveDates)
}
} else if (minDate.monthInt == displayDate.monthInt) || (maxDate.monthInt == displayDate.monthInt) {
if (minDate.monthInt == displayDate.monthInt) {
// validate days to enable/disable
if let day:Int = Int(numberLabel.text), day < minDate.dayInt {
disableLabel(with: surface)
} else {
numberLabel.isEnabled = false
handleActiveDates(with: displayDate, activeDates: activeDates, inactiveDates: inactiveDates)
}
} else if (maxDate.monthInt == displayDate.monthInt) {
// validate days to enable/disable
if let day:Int = Int(numberLabel.text), day > maxDate.dayInt {
disableLabel(with: surface)
} else {
numberLabel.isEnabled = false
handleActiveDates(with: displayDate, activeDates: activeDates, inactiveDates: inactiveDates)
}
}
} else if ((minDate.monthInt < displayDate.monthInt) || (displayDate.monthInt < maxDate.monthInt)) {
// enable all days if no active dates
// handing active dates
enableAllDaysAndCheckActiveDates(with: surface, displayDate: displayDate, activeDates: activeDates, inactiveDates: inactiveDates)
}
} else {
// enable all days if no active dates
// handing active dates
enableAllDaysAndCheckActiveDates(with: surface, displayDate: displayDate, activeDates: activeDates, inactiveDates: inactiveDates)
}
}
func addIndicator(with color: UIColor, surface: Surface, clearFullCircle: Bool, drawSemiCircle: Bool) {
// add indicator
let indicatorView: View = View().with {