Skip to content

Commit

Permalink
Fix layout for calendars where first week day is different from Monda…
Browse files Browse the repository at this point in the history
…y. Related issue #18
  • Loading branch information
ilia3546 committed Sep 12, 2022
1 parent a50ebea commit 1abd832
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 34 deletions.
16 changes: 16 additions & 0 deletions Sources/Extensions/Calendar+LastWeekday.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// File.swift
//
//
// Created by Ilya Kharlamov on 9/12/22.
//

import Foundation

internal extension Calendar {
var lastWeekday: Int {
let numDays = self.weekdaySymbols.count
let res = (self.firstWeekday + numDays - 1) % numDays
return res != 0 ? res : self.weekdaySymbols.count
}
}
7 changes: 7 additions & 0 deletions Sources/Models/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ public struct FastisConfig {

private init() {}

/**
Base calendar used to build a view

Default value — `.current`
*/
public var calendar: Calendar = .current

/// Base view controller (`cancelButtonTitle`, `doneButtonTitle`, etc.)
public var controller = FastisConfig.Controller()

Expand Down
46 changes: 23 additions & 23 deletions Sources/Views/Controller.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ open class FastisController<Value: FastisValue>: UIViewController, JTACMonthView
}()

private lazy var weekView: WeekView = {
let view = WeekView(config: self.config.weekView)
let view = WeekView(calendar: self.config.calendar, config: self.config.weekView)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
Expand Down Expand Up @@ -139,7 +139,6 @@ open class FastisController<Value: FastisValue>: UIViewController, JTACMonthView
private let dayCellReuseIdentifier = "DayCellReuseIdentifier"
private let monthHeaderReuseIdentifier = "MonthHeaderReuseIdentifier"
private var viewConfigs: [IndexPath: DayCell.ViewConfig] = [:]
private var currentCalendar: Calendar = .autoupdatingCurrent
private var privateMinimumDate: Date?
private var privateMaximumDate: Date?
private var privateSelectMonthOnHeaderTap: Bool = false
Expand Down Expand Up @@ -347,7 +346,8 @@ open class FastisController<Value: FastisValue>: UIViewController, JTACMonthView
let newConfig = DayCell.makeViewConfig(for: cellState,
minimumDate: self.privateMinimumDate,
maximumDate: self.privateMaximumDate,
rangeValue: self.value as? FastisRange)
rangeValue: self.value as? FastisRange,
calendar: self.config.calendar)
self.viewConfigs[indexPath] = newConfig
cell.applyConfig(self.config)
cell.configure(for: newConfig)
Expand Down Expand Up @@ -399,23 +399,23 @@ open class FastisController<Value: FastisValue>: UIViewController, JTACMonthView
let dateRangeChangesDisabled = !allowDateRangeChanges
let rangeSelected = !currentValue.fromDate.isInSameDay(date: currentValue.toDate)
if dateRangeChangesDisabled && rangeSelected {
newValue = .from(date.startOfDay(in: self.currentCalendar), to: date.endOfDay(in: self.currentCalendar))
} else if date.isInSameDay(in: self.currentCalendar, date: currentValue.fromDate) {
let newToDate = date.endOfDay(in: self.currentCalendar)
newValue = .from(date.startOfDay(in: self.config.calendar), to: date.endOfDay(in: self.config.calendar))
} else if date.isInSameDay(in: self.config.calendar, date: currentValue.fromDate) {
let newToDate = date.endOfDay(in: self.config.calendar)
newValue = .from(currentValue.fromDate, to: newToDate)
} else if date.isInSameDay(in: self.currentCalendar, date: currentValue.toDate) {
let newFromDate = date.startOfDay(in: self.currentCalendar)
} else if date.isInSameDay(in: self.config.calendar, date: currentValue.toDate) {
let newFromDate = date.startOfDay(in: self.config.calendar)
newValue = .from(newFromDate, to: currentValue.toDate)
} else if date < currentValue.fromDate {
let newFromDate = date.startOfDay(in: self.currentCalendar)
let newFromDate = date.startOfDay(in: self.config.calendar)
newValue = .from(newFromDate, to: currentValue.toDate)
} else {
let newToDate = date.endOfDay(in: self.currentCalendar)
let newToDate = date.endOfDay(in: self.config.calendar)
newValue = .from(currentValue.fromDate, to: newToDate)
}

} else {
newValue = .from(date.startOfDay(in: self.currentCalendar), to: date.endOfDay(in: self.currentCalendar))
newValue = .from(date.startOfDay(in: self.config.calendar), to: date.endOfDay(in: self.config.calendar))
}

self.value = newValue as? Value
Expand All @@ -441,30 +441,30 @@ open class FastisController<Value: FastisValue>: UIViewController, JTACMonthView

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy MM dd"
dateFormatter.timeZone = self.currentCalendar.timeZone
dateFormatter.locale = self.currentCalendar.locale
dateFormatter.timeZone = self.config.calendar.timeZone
dateFormatter.locale = self.config.calendar.locale
var startDate = dateFormatter.date(from: "2000 01 01")!
var endDate = dateFormatter.date(from: "2030 12 01")!

if let maximumDate = self.privateMaximumDate,
let endOfNextMonth = self.currentCalendar.date(byAdding: .month, value: 2, to: maximumDate)?
.endOfMonth(in: self.currentCalendar) {
let endOfNextMonth = self.config.calendar.date(byAdding: .month, value: 2, to: maximumDate)?
.endOfMonth(in: self.config.calendar) {
endDate = endOfNextMonth
}

if let minimumDate = self.privateMinimumDate,
let startOfPreviousMonth = self.currentCalendar.date(byAdding: .month, value: -2, to: minimumDate)?
.startOfMonth(in: self.currentCalendar) {
let startOfPreviousMonth = self.config.calendar.date(byAdding: .month, value: -2, to: minimumDate)?
.startOfMonth(in: self.config.calendar) {
startDate = startOfPreviousMonth
}

let parameters = ConfigurationParameters(startDate: startDate,
endDate: endDate,
numberOfRows: 6,
calendar: self.currentCalendar,
calendar: self.config.calendar,
generateInDates: .forAllMonths,
generateOutDates: .tillEndOfRow,
firstDayOfWeek: .monday,
firstDayOfWeek: nil,
hasStrictBoundaries: true)
return parameters
}
Expand All @@ -475,16 +475,16 @@ open class FastisController<Value: FastisValue>: UIViewController, JTACMonthView
header.configure(for: range.start)
if self.privateSelectMonthOnHeaderTap, Value.mode == .range {
header.tapHandler = {
var fromDate = range.start.startOfMonth(in: self.currentCalendar)
var toDate = range.start.endOfMonth(in: self.currentCalendar)
var fromDate = range.start.startOfMonth(in: self.config.calendar)
var toDate = range.start.endOfMonth(in: self.config.calendar)
if let minDate = self.minimumDate {
if toDate < minDate { return } else if fromDate < minDate {
fromDate = minDate.startOfDay(in: self.currentCalendar)
fromDate = minDate.startOfDay(in: self.config.calendar)
}
}
if let maxDate = self.maximumDate {
if fromDate > maxDate { return } else if toDate > maxDate {
toDate = maxDate.endOfDay(in: self.currentCalendar)
toDate = maxDate.endOfDay(in: self.config.calendar)
}
}
let newValue: FastisRange = .from(fromDate, to: toDate)
Expand Down
20 changes: 13 additions & 7 deletions Sources/Views/DayCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,13 @@ class DayCell: JTACDayCell {
NSLayoutConstraint.activate(self.rangeViewBottomAnchorConstraints)
}

public static func makeViewConfig(for state: CellState, minimumDate: Date?, maximumDate: Date?, rangeValue: FastisRange?) -> ViewConfig {
public static func makeViewConfig(
for state: CellState,
minimumDate: Date?,
maximumDate: Date?,
rangeValue: FastisRange?,
calendar: Calendar
) -> ViewConfig {

var config = ViewConfig()

Expand Down Expand Up @@ -162,10 +168,10 @@ class DayCell: JTACDayCell {

if showRangeView {

if state.day == .monday {
if state.day.rawValue == calendar.firstWeekday {
config.rangeView.leftSideState = .rounded
config.rangeView.rightSideState = .squared
} else if state.day == .sunday {
} else if state.day.rawValue == calendar.lastWeekday {
config.rangeView.leftSideState = .squared
config.rangeView.rightSideState = .rounded
} else {
Expand Down Expand Up @@ -201,10 +207,10 @@ class DayCell: JTACDayCell {
case .left, .right, .middle:
config.isSelectedViewHidden = position == .middle

if position == .right && state.day == .monday {
if position == .right && state.day.rawValue == calendar.firstWeekday {
config.rangeView.leftSideState = .rounded

} else if position == .left && state.day == .sunday {
} else if position == .left && state.day.rawValue == calendar.lastWeekday {
config.rangeView.rightSideState = .rounded

} else if position == .left {
Expand All @@ -213,11 +219,11 @@ class DayCell: JTACDayCell {
} else if position == .right {
config.rangeView.leftSideState = .squared

} else if state.day == .monday {
} else if state.day.rawValue == calendar.firstWeekday {
config.rangeView.leftSideState = .rounded
config.rangeView.rightSideState = .squared

} else if state.day == .sunday {
} else if state.day.rawValue == calendar.lastWeekday {
config.rangeView.leftSideState = .squared
config.rangeView.rightSideState = .rounded

Expand Down
13 changes: 9 additions & 4 deletions Sources/Views/WeekView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ class WeekView: UIView {
// MARK: - Variables

private let config: FastisConfig.WeekView
private let calendar: Calendar

// MARK: - Lifecycle

init(config: FastisConfig.WeekView) {
init(calendar: Calendar, config: FastisConfig.WeekView) {
self.config = config
self.calendar = calendar
super.init(frame: .zero)
self.configureUI()
self.configureSubviews()
Expand All @@ -50,9 +52,11 @@ class WeekView: UIView {
}

private func configureSubviews() {
var weekDays = self.config.calendar.shortWeekdaySymbols
weekDays.append(weekDays.remove(at: 0))
for weekdaySymbol in weekDays {
let numDays = self.calendar.shortStandaloneWeekdaySymbols.count
let first = self.calendar.firstWeekday - 1
let end = first + numDays - 1
let days = (first...end).map({ self.calendar.shortStandaloneWeekdaySymbols[$0 % numDays] })
for weekdaySymbol in days {
self.stackView.addArrangedSubview(self.makeWeekLabel(for: weekdaySymbol))
}
self.addSubview(self.stackView)
Expand Down Expand Up @@ -95,6 +99,7 @@ extension FastisConfig {

Default value — `.current`
*/
@available(*, unavailable, message: "Use FastisConfig.calendar propery instead")
public var calendar: Calendar = .current

/**
Expand Down

0 comments on commit 1abd832

Please sign in to comment.