Digital ACT-191 ONEAPP-7958 story: added action for next and previous on changing min / max dates
This commit is contained in:
parent
80f90e0b56
commit
450dd1aae8
@ -79,7 +79,8 @@ open class CalendarBase: View {
|
|||||||
private var selectedIndexPath : IndexPath?
|
private var selectedIndexPath : IndexPath?
|
||||||
private var dates: [Date] = []
|
private var dates: [Date] = []
|
||||||
private var days: [String] = []
|
private var days: [String] = []
|
||||||
|
private var displayDate: Date = Date()
|
||||||
|
|
||||||
internal var containerView = View().with {
|
internal var containerView = View().with {
|
||||||
$0.clipsToBounds = true
|
$0.clipsToBounds = true
|
||||||
}
|
}
|
||||||
@ -146,8 +147,14 @@ open class CalendarBase: View {
|
|||||||
|
|
||||||
open override func updateView() {
|
open override func updateView() {
|
||||||
super.updateView()
|
super.updateView()
|
||||||
self.fetchDates(with: selectedDate)
|
// range check between min & max dates
|
||||||
collectionView.reloadData()
|
if (minDate <= maxDate) {
|
||||||
|
// Check if current date falls between min & max dates.
|
||||||
|
let fallsBetween = displayDate.isBetweeen(date: minDate, andDate: maxDate)
|
||||||
|
displayDate = fallsBetween ? displayDate : minDate
|
||||||
|
self.fetchDates(with: displayDate)
|
||||||
|
collectionView.reloadData()
|
||||||
|
}
|
||||||
layer.backgroundColor = backgroundColorConfiguration.getColor(self).cgColor
|
layer.backgroundColor = backgroundColorConfiguration.getColor(self).cgColor
|
||||||
if hideContainerBorder {
|
if hideContainerBorder {
|
||||||
layer.borderColor = nil
|
layer.borderColor = nil
|
||||||
@ -171,12 +178,12 @@ open class CalendarBase: View {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Methods
|
// MARK: - Private Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
func fetchDates(with date:Date) {
|
func fetchDates(with aDate:Date) {
|
||||||
days.removeAll()
|
days.removeAll()
|
||||||
self.dates = selectedDate.calendarDisplayDays
|
self.dates = aDate.calendarDisplayDays
|
||||||
for date in dates {
|
for date in dates {
|
||||||
// code to be executed
|
// code to be executed
|
||||||
if date.monthInt != selectedDate.monthInt {
|
if date.monthInt != aDate.monthInt {
|
||||||
days.append("")
|
days.append("")
|
||||||
} else {
|
} else {
|
||||||
days.append(getDay(with: date))
|
days.append(getDay(with: date))
|
||||||
@ -216,7 +223,7 @@ extension CalendarBase: UICollectionViewDelegate, UICollectionViewDataSource, UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell.update(with: surface, indicators: indicators, text: days[indexPath.row], indicatorCount: indicatorCount, selectedDate: selectedDate, hideDate: hideCurrentDateIndicator, minDate: minDate, maxDate: maxDate, activeDates: activeDates, inactiveDates: inactiveDates)
|
cell.update(with: surface, indicators: indicators, text: days[indexPath.row], indicatorCount: indicatorCount, selectedDate: selectedDate, displayDate: displayDate, hideDate: hideCurrentDateIndicator, minDate: minDate, maxDate: maxDate, activeDates: activeDates, inactiveDates: inactiveDates)
|
||||||
if (self.days[indexPath.row] == self.getDay(with: selectedDate)) { selectedIndexPath = indexPath }
|
if (self.days[indexPath.row] == self.getDay(with: selectedDate)) { selectedIndexPath = indexPath }
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
@ -227,7 +234,36 @@ extension CalendarBase: UICollectionViewDelegate, UICollectionViewDataSource, UI
|
|||||||
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: CalendarHeaderReusableView.identifier, for: indexPath) as? CalendarHeaderReusableView else {
|
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: CalendarHeaderReusableView.identifier, for: indexPath) as? CalendarHeaderReusableView else {
|
||||||
return UICollectionReusableView()
|
return UICollectionReusableView()
|
||||||
}
|
}
|
||||||
header.configure(with: surface)
|
var nextEnabled = false
|
||||||
|
var prevEnabled = false
|
||||||
|
|
||||||
|
// check the interval between min date, max date.. set enable/disable flag for next / previous buttons.
|
||||||
|
if ((displayDate.monthInt < maxDate.monthInt) && (displayDate.yearInt == maxDate.yearInt)) || (displayDate.yearInt < maxDate.yearInt) {
|
||||||
|
nextEnabled = true
|
||||||
|
}
|
||||||
|
if ((minDate.monthInt < displayDate.monthInt) && (minDate.yearInt == displayDate.yearInt)) || (minDate.yearInt < displayDate.yearInt) {
|
||||||
|
prevEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
header.nextClicked = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
let aDate = Calendar.current.date(byAdding: .month, value: 1, to:self.displayDate)!
|
||||||
|
if ((aDate.monthInt <= maxDate.monthInt) && (aDate.yearInt == maxDate.yearInt)) || (aDate.yearInt < maxDate.yearInt) {
|
||||||
|
displayDate = aDate
|
||||||
|
self.fetchDates(with: displayDate)
|
||||||
|
self.collectionView.reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header.previousClicked = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
let aDate = Calendar.current.date(byAdding: .month, value: -1, to:self.displayDate)!
|
||||||
|
if ((minDate.monthInt <= aDate.monthInt) && (minDate.yearInt == aDate.yearInt)) || (minDate.yearInt < aDate.yearInt) {
|
||||||
|
displayDate = aDate
|
||||||
|
self.fetchDates(with: displayDate)
|
||||||
|
self.collectionView.reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header.update(with: surface, aDate: displayDate, nextEnabled: nextEnabled, previousEnabled: prevEnabled)
|
||||||
return header
|
return header
|
||||||
} else {
|
} else {
|
||||||
// Footer
|
// Footer
|
||||||
|
|||||||
@ -94,12 +94,12 @@ final class CalendarDateCollectionViewCell: UICollectionViewCell {
|
|||||||
|
|
||||||
/// Updating UI based on selected date, modified indicators data along with surface
|
/// 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
|
/// 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, hideDate: Bool, minDate: Date, maxDate: Date, activeDates: [Date], inactiveDates: [Date]) {
|
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]) {
|
||||||
numberLabel.surface = surface
|
numberLabel.surface = surface
|
||||||
numberLabel.text = text
|
numberLabel.text = text
|
||||||
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
|
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
|
||||||
|
|
||||||
// disabled cells based on min date, max date.
|
// enable/disable cells based on min date, max date.
|
||||||
if let day:Int = Int(numberLabel.text), day < minDate.dayInt || day > maxDate.dayInt {
|
if let day:Int = Int(numberLabel.text), day < minDate.dayInt || day > maxDate.dayInt {
|
||||||
numberLabel.isEnabled = false
|
numberLabel.isEnabled = false
|
||||||
numberLabel.textColor = disabledTextColorConfiguration.getColor(surface)
|
numberLabel.textColor = disabledTextColorConfiguration.getColor(surface)
|
||||||
@ -121,16 +121,18 @@ final class CalendarDateCollectionViewCell: UICollectionViewCell {
|
|||||||
// handling inactive dates
|
// handling inactive dates
|
||||||
if inactiveDates.count > 0 {
|
if inactiveDates.count > 0 {
|
||||||
for x in (0...(inactiveDates.count-1)) {
|
for x in (0...(inactiveDates.count-1)) {
|
||||||
if let day:Int = Int(numberLabel.text), day == inactiveDates[x].dayInt {
|
if (activeDates[x].monthInt == displayDate.monthInt) && (activeDates[x].yearInt == displayDate.yearInt) {
|
||||||
numberLabel.isEnabled = false
|
if let day:Int = Int(numberLabel.text), day == inactiveDates[x].dayInt {
|
||||||
numberLabel.textColor = disabledTextColorConfiguration.getColor(surface)
|
numberLabel.isEnabled = false
|
||||||
layer.backgroundColor = disabledBackgroundColor.getColor(surface).cgColor
|
numberLabel.textColor = disabledTextColorConfiguration.getColor(surface)
|
||||||
|
layer.backgroundColor = disabledBackgroundColor.getColor(surface).cgColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update text color, bg color, corner radius
|
// update text color, bg color, corner radius
|
||||||
if (numberLabel.text == self.getDay(with: selectedDate)) && numberLabel.isEnabled {
|
if (numberLabel.text == self.getDay(with: selectedDate)) && (selectedDate.monthInt == displayDate.monthInt) && (selectedDate.yearInt == displayDate.yearInt) && numberLabel.isEnabled {
|
||||||
numberLabel.textColor = selectedTextColorConfiguration.getColor(surface)
|
numberLabel.textColor = selectedTextColorConfiguration.getColor(surface)
|
||||||
layer.backgroundColor = selectedBackgroundColor.getColor(surface).cgColor
|
layer.backgroundColor = selectedBackgroundColor.getColor(surface).cgColor
|
||||||
layer.cornerRadius = VDSFormControls.borderRadius
|
layer.cornerRadius = VDSFormControls.borderRadius
|
||||||
@ -142,8 +144,6 @@ final class CalendarDateCollectionViewCell: UICollectionViewCell {
|
|||||||
|
|
||||||
// add indicators
|
// add indicators
|
||||||
if indicatorCount > 0 {
|
if indicatorCount > 0 {
|
||||||
// let width = (indicatorCount * 8) + (Int(VDSLayout.space1X) * (indicatorCount - 1))
|
|
||||||
// stackView.widthAnchor.constraint(equalToConstant: CGFloat(width)).activate()
|
|
||||||
for x in (0...(indicators.count-1)) {
|
for x in (0...(indicators.count-1)) {
|
||||||
if (self.numberLabel.text == self.getDay(with: indicators[x].date)) {
|
if (self.numberLabel.text == self.getDay(with: indicators[x].date)) {
|
||||||
let color = (numberLabel.text == self.getDay(with: selectedDate)) ? selectedCellIndicatorColorConfiguration.getColor(surface) : unselectedCellIndicatorColorConfiguration.getColor(surface)
|
let color = (numberLabel.text == self.getDay(with: selectedDate)) ? selectedCellIndicatorColorConfiguration.getColor(surface) : unselectedCellIndicatorColorConfiguration.getColor(surface)
|
||||||
@ -153,7 +153,7 @@ final class CalendarDateCollectionViewCell: UICollectionViewCell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update text style for current date
|
// update text style for current date
|
||||||
if (numberLabel.text == self.getDay(with: currentDate)) {
|
if (numberLabel.text == self.getDay(with: currentDate)) && (currentDate.monthInt == displayDate.monthInt) {
|
||||||
numberLabel.textStyle = hideDate ? .bodySmall : .boldBodySmall
|
numberLabel.textStyle = hideDate ? .bodySmall : .boldBodySmall
|
||||||
} else {
|
} else {
|
||||||
numberLabel.textStyle = .bodySmall
|
numberLabel.textStyle = .bodySmall
|
||||||
|
|||||||
@ -10,25 +10,19 @@ import UIKit
|
|||||||
import VDSTokens
|
import VDSTokens
|
||||||
|
|
||||||
/// Header view to display month and year along with days of week
|
/// Header view to display month and year along with days of week
|
||||||
open class CalendarHeaderView: View {
|
class CalendarHeaderReusableView: UICollectionReusableView {
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Initializers
|
|
||||||
//--------------------------------------------------
|
|
||||||
required public init() {
|
|
||||||
super.init(frame: .zero)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override init(frame: CGRect) {
|
///Identifier for the Calendar Header Reusable View
|
||||||
super.init(frame: .zero)
|
static let identifier: String = String(describing: CalendarHeaderReusableView.self)
|
||||||
}
|
|
||||||
|
|
||||||
public required init?(coder: NSCoder) {
|
|
||||||
super.init(coder: coder)
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
/// A callback when the next button clicked
|
||||||
|
public var nextClicked: (() -> (Void))?
|
||||||
|
|
||||||
|
/// A callback when the previous button clicked
|
||||||
|
public var previousClicked: (() -> (Void))?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Properties
|
// MARK: - Private Properties
|
||||||
@ -64,6 +58,9 @@ open class CalendarHeaderView: View {
|
|||||||
return collectionView
|
return collectionView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private var surface: Surface = .light
|
||||||
|
private var displayDate: Date = Date()
|
||||||
|
|
||||||
internal var previousMonthView = View()
|
internal var previousMonthView = View()
|
||||||
internal var nextMonthView = View()
|
internal var nextMonthView = View()
|
||||||
let viewSize = 40.0
|
let viewSize = 40.0
|
||||||
@ -84,7 +81,7 @@ open class CalendarHeaderView: View {
|
|||||||
$0.size = .small
|
$0.size = .small
|
||||||
}
|
}
|
||||||
|
|
||||||
internal var monthYearLabel = Label().with {
|
internal var headerTitle = Label().with {
|
||||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||||
$0.textAlignment = .center
|
$0.textAlignment = .center
|
||||||
$0.numberOfLines = 1
|
$0.numberOfLines = 1
|
||||||
@ -94,17 +91,23 @@ open class CalendarHeaderView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal let daysOfWeek = Date.capitalizedFirstLettersOfWeekdays
|
internal let daysOfWeek = Date.capitalizedFirstLettersOfWeekdays
|
||||||
internal let monthYearLabelTextColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
internal let headerTitleTextColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Lifecycle
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
open override func initialSetup() {
|
override init(frame: CGRect) {
|
||||||
super.initialSetup()
|
super.init(frame: frame)
|
||||||
|
setUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func setup() {
|
required init?(coder: NSCoder) {
|
||||||
super.setup()
|
super.init(coder: coder)
|
||||||
|
setUp()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuring the cell with default setup
|
||||||
|
private func setUp() {
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
|
|
||||||
// stackview
|
// stackview
|
||||||
@ -114,7 +117,7 @@ open class CalendarHeaderView: View {
|
|||||||
.pinBottom(VDSLayout.space1X)
|
.pinBottom(VDSLayout.space1X)
|
||||||
.pinLeading()
|
.pinLeading()
|
||||||
.pinTrailing()
|
.pinTrailing()
|
||||||
.height(containerSize.height)
|
.height(containerSize.height - VDSLayout.space1X)
|
||||||
.width(containerSize.width)
|
.width(containerSize.width)
|
||||||
stackView.centerXAnchor.constraint(equalTo: centerXAnchor).activate()
|
stackView.centerXAnchor.constraint(equalTo: centerXAnchor).activate()
|
||||||
|
|
||||||
@ -128,43 +131,49 @@ open class CalendarHeaderView: View {
|
|||||||
previousMonthView.widthAnchor.constraint(equalToConstant: viewSize).activate()
|
previousMonthView.widthAnchor.constraint(equalToConstant: viewSize).activate()
|
||||||
previousMonthView.addSubview(previousButton)
|
previousMonthView.addSubview(previousButton)
|
||||||
previousButton.pinCenterY().pinCenterX()
|
previousButton.pinCenterY().pinCenterX()
|
||||||
|
previousButton.onClick = { _ in self.previousButtonClick() }
|
||||||
|
|
||||||
// month year label
|
// month year label
|
||||||
topHeaderView.addArrangedSubview(monthYearLabel)
|
topHeaderView.addArrangedSubview(headerTitle)
|
||||||
|
|
||||||
// next button
|
// next button
|
||||||
topHeaderView.addArrangedSubview(nextMonthView)
|
topHeaderView.addArrangedSubview(nextMonthView)
|
||||||
nextMonthView.widthAnchor.constraint(equalToConstant: viewSize).activate()
|
nextMonthView.widthAnchor.constraint(equalToConstant: viewSize).activate()
|
||||||
nextMonthView.addSubview(nextButton)
|
nextMonthView.addSubview(nextButton)
|
||||||
nextButton.pinCenterY().pinCenterX()
|
nextButton.pinCenterY().pinCenterX()
|
||||||
|
nextButton.onClick = { _ in self.nextButtonClick() }
|
||||||
|
|
||||||
// days Collection View
|
// days Collection View
|
||||||
stackView.addArrangedSubview(daysCollectionView)
|
stackView.addArrangedSubview(daysCollectionView)
|
||||||
topHeaderView.heightAnchor.constraint(equalToConstant: viewSize).isActive = true
|
topHeaderView.heightAnchor.constraint(equalToConstant: viewSize).isActive = true
|
||||||
daysCollectionView.centerXAnchor.constraint(equalTo: centerXAnchor).activate()
|
daysCollectionView.centerXAnchor.constraint(equalTo: centerXAnchor).activate()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func updateView() {
|
/// Updating UI based on next/previous clicks along with surface.
|
||||||
super.updateView()
|
/// Updating UI to enable/disable the next & previous buttons, updating header title
|
||||||
monthYearLabel.surface = surface
|
func update(with surface: Surface, aDate: Date, nextEnabled: Bool, previousEnabled: Bool) {
|
||||||
|
self.surface = surface
|
||||||
|
headerTitle.surface = surface
|
||||||
previousButton.surface = surface
|
previousButton.surface = surface
|
||||||
nextButton.surface = surface
|
nextButton.surface = surface
|
||||||
|
nextButton.isEnabled = nextEnabled
|
||||||
|
previousButton.isEnabled = previousEnabled
|
||||||
daysCollectionView.reloadData()
|
daysCollectionView.reloadData()
|
||||||
monthYearLabel.text = "May 2024"
|
let labelText = aDate.getMonthName(date: aDate) + " \(aDate.yearInt)"
|
||||||
monthYearLabel.textColor = monthYearLabelTextColorConfiguration.getColor(surface)
|
headerTitle.text = labelText
|
||||||
|
headerTitle.textColor = headerTitleTextColorConfiguration.getColor(surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
override open func layoutSubviews() {
|
func nextButtonClick() {
|
||||||
super.layoutSubviews()
|
nextClicked?()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func reset() {
|
func previousButtonClick() {
|
||||||
super.reset()
|
previousClicked?()
|
||||||
monthYearLabel.textStyle = .boldBodySmall
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CalendarHeaderView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
extension CalendarHeaderReusableView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
||||||
|
|
||||||
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
return daysOfWeek.count
|
return daysOfWeek.count
|
||||||
@ -172,7 +181,7 @@ extension CalendarHeaderView: UICollectionViewDelegate, UICollectionViewDataSour
|
|||||||
|
|
||||||
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionViewCell.identifier, for: indexPath) as? collectionViewCell else { return UICollectionViewCell() }
|
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionViewCell.identifier, for: indexPath) as? collectionViewCell else { return UICollectionViewCell() }
|
||||||
cell.updateTitle(text: daysOfWeek[indexPath.row], surface: surface)
|
cell.updateTitle(text: daysOfWeek[indexPath.row], surface: self.surface)
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,28 +8,6 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import VDSTokens
|
import VDSTokens
|
||||||
|
|
||||||
/// Custom header view
|
|
||||||
class CalendarHeaderReusableView: UICollectionReusableView {
|
|
||||||
|
|
||||||
///Identifier for the Calendar Header Reusable View
|
|
||||||
static let identifier: String = String(describing: CalendarHeaderReusableView.self)
|
|
||||||
|
|
||||||
private lazy var headerView = CalendarHeaderView()
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func configure(with surface: Surface) {
|
|
||||||
headerView.surface = surface
|
|
||||||
addSubview(headerView)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Custom footer view
|
/// Custom footer view
|
||||||
class CalendarFooterReusableView: UICollectionReusableView {
|
class CalendarFooterReusableView: UICollectionReusableView {
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension Date {
|
extension Date {
|
||||||
|
|
||||||
static var firstDayOfWeek = Calendar.current.firstWeekday
|
static var firstDayOfWeek = Calendar.current.firstWeekday
|
||||||
|
|
||||||
|
/// Capitalizes the first letter of the day of the week
|
||||||
static var capitalizedFirstLettersOfWeekdays: [String] {
|
static var capitalizedFirstLettersOfWeekdays: [String] {
|
||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
let weekdays = calendar.shortWeekdaySymbols
|
let weekdays = calendar.shortWeekdaySymbols
|
||||||
@ -19,6 +22,18 @@ extension Date {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns all month names
|
||||||
|
static var fullMonthNames: [String] {
|
||||||
|
let dateFormatter = DateFormatter()
|
||||||
|
dateFormatter.locale = Locale.current
|
||||||
|
|
||||||
|
return (1...12).compactMap { month in
|
||||||
|
dateFormatter.setLocalizedDateFormatFromTemplate("MMMM")
|
||||||
|
let date = Calendar.current.date(from: DateComponents(year: 2000, month: month, day: 1))
|
||||||
|
return date.map { dateFormatter.string(from: $0) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var startOfMonth: Date {
|
var startOfMonth: Date {
|
||||||
Calendar.current.dateInterval(of: .month, for: self)!.start
|
Calendar.current.dateInterval(of: .month, for: self)!.start
|
||||||
}
|
}
|
||||||
@ -28,6 +43,7 @@ extension Date {
|
|||||||
return Calendar.current.date(byAdding: .day, value: -1, to: lastDay)!
|
return Calendar.current.date(byAdding: .day, value: -1, to: lastDay)!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the number of days of the month
|
||||||
var numberOfDaysInMonth: Int {
|
var numberOfDaysInMonth: Int {
|
||||||
Calendar.current.component(.day, from: endOfMonth)
|
Calendar.current.component(.day, from: endOfMonth)
|
||||||
}
|
}
|
||||||
@ -41,6 +57,7 @@ extension Date {
|
|||||||
return Calendar.current.date(byAdding: .day, value: -numberFromPreviousMonth, to: startOfMonth)!
|
return Calendar.current.date(byAdding: .day, value: -numberFromPreviousMonth, to: startOfMonth)!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the days of the month to display
|
||||||
var calendarDisplayDays: [Date] {
|
var calendarDisplayDays: [Date] {
|
||||||
var days: [Date] = []
|
var days: [Date] = []
|
||||||
// Start with days from the previous month to fill the grid
|
// Start with days from the previous month to fill the grid
|
||||||
@ -58,11 +75,30 @@ extension Date {
|
|||||||
return days
|
return days
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the year value of the given date
|
||||||
|
var yearInt: Int {
|
||||||
|
Calendar.current.component(.year, from: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the month value of the given date
|
||||||
var monthInt: Int {
|
var monthInt: Int {
|
||||||
Calendar.current.component(.month, from: self)
|
Calendar.current.component(.month, from: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the day value of the given date
|
||||||
var dayInt: Int {
|
var dayInt: Int {
|
||||||
Calendar.current.component(.day, from: self)
|
Calendar.current.component(.day, from: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the date falls between the given dates
|
||||||
|
func isBetweeen(date date1: Date, andDate date2: Date) -> Bool {
|
||||||
|
return date1.compare(self) == self.compare(date2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the month name of the given date
|
||||||
|
func getMonthName(date: Date) -> String {
|
||||||
|
let names = Date.fullMonthNames
|
||||||
|
return names[date.monthInt - 1]
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user