From fe26eac659b754b0e204984ab3f51588c701d9a3 Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Fri, 17 Jul 2020 00:36:05 -0700 Subject: [PATCH] Custom width (#4) * added code for more flexible monthly view width * updated elegantpages * updated elegantpages * updated based on new elegantpages syntax * new elegantpages --- Example/Example.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- Example/Example/Info.plist | 2 - Package.resolved | 4 +- Package.swift | 2 +- .../Helpers/Models/CalenderConstants.swift | 11 ++-- .../ElegantCalendarManager.swift | 15 +++-- .../MonthlyCalendarManager.swift | 59 +++++++------------ .../Models/Protocols/Calendar+Buildable.swift | 5 +- .../Views/ElegantCalendarView.swift | 5 +- .../Views/Monthly/MonthView.swift | 2 +- .../Views/Monthly/MonthlyCalendarView.swift | 41 +++++++++++-- .../Views/Yearly/YearView.swift | 2 +- .../Views/Yearly/YearlyCalendarView.swift | 2 +- 14 files changed, 86 insertions(+), 70 deletions(-) diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 4239cdd..d9b5275 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -658,7 +658,7 @@ repositoryURL = "https://github.com/ThasianX/ElegantPages"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.2.0; + minimumVersion = 1.4.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index e887f74..51140d5 100644 --- a/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/ThasianX/ElegantPages", "state": { "branch": null, - "revision": "2702cc471c7a1b63d94b6e598f6416d65fe6e22f", - "version": "1.2.1" + "revision": "7eb457484e04375d7e6a3ca442a98cbe75ead7b0", + "version": "1.4.0" } } ] diff --git a/Example/Example/Info.plist b/Example/Example/Info.plist index 9742bf0..cb967d4 100644 --- a/Example/Example/Info.plist +++ b/Example/Example/Info.plist @@ -46,8 +46,6 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad diff --git a/Package.resolved b/Package.resolved index 17d0136..51140d5 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/ThasianX/ElegantPages", "state": { "branch": null, - "revision": "a7a5d37538a127d134104ee1743814d7cc597bf5", - "version": "1.2.2" + "revision": "7eb457484e04375d7e6a3ca442a98cbe75ead7b0", + "version": "1.4.0" } } ] diff --git a/Package.swift b/Package.swift index 0f0aaa6..db4d05d 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,7 @@ let package = Package( targets: ["ElegantCalendar"]), ], dependencies: [ - .package(url: "https://github.com/ThasianX/ElegantPages", from: "1.2.0") + .package(url: "https://github.com/ThasianX/ElegantPages", from: "1.4.0") ], targets: [ .target( diff --git a/Sources/ElegantCalendar/Helpers/Models/CalenderConstants.swift b/Sources/ElegantCalendar/Helpers/Models/CalenderConstants.swift index a0200bd..df852b8 100644 --- a/Sources/ElegantCalendar/Helpers/Models/CalenderConstants.swift +++ b/Sources/ElegantCalendar/Helpers/Models/CalenderConstants.swift @@ -3,20 +3,18 @@ import SwiftUI let screen = UIScreen.main.bounds -let window = UIApplication.shared.windows.filter { $0.isKeyWindow }.first -let statusBarHeight = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0 struct CalendarConstants { static let cellHeight: CGFloat = screen.height - static let cellWidth: CGFloat = screen.width - - static let horizontalPadding: CGFloat = cellWidth * 0.058 static let daysInRow: CGFloat = 7 struct Monthly { + static var cellWidth: CGFloat! + static let horizontalPadding: CGFloat = cellWidth * 0.045 + static let outerHorizontalPadding: CGFloat = horizontalPadding + dayWidth/4 static let topPadding: CGFloat = cellHeight * 0.078 @@ -32,6 +30,9 @@ struct CalendarConstants { struct Yearly { + static let cellWidth: CGFloat = screen.width + static let horizontalPadding: CGFloat = cellWidth * 0.058 + static let outerHorizontalPadding: CGFloat = horizontalPadding + monthWidth/7 static let topPadding: CGFloat = cellHeight * 0.12 diff --git a/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/ElegantCalendarManager.swift b/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/ElegantCalendarManager.swift index 6410fcc..9273d7b 100644 --- a/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/ElegantCalendarManager.swift +++ b/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/ElegantCalendarManager.swift @@ -15,7 +15,7 @@ public class ElegantCalendarManager: ObservableObject { } public var isShowingYearView: Bool { - pagerManager.currentPage == 0 + pagesManager.currentPage == 0 } @Published public var datasource: ElegantCalendarDataSource? @@ -26,7 +26,7 @@ public class ElegantCalendarManager: ObservableObject { @Published public var yearlyManager: YearlyCalendarManager @Published public var monthlyManager: MonthlyCalendarManager - let pagerManager: ElegantPagesManager + let pagesManager: ElegantPagesManager private var anyCancellable = Set() @@ -38,9 +38,8 @@ public class ElegantCalendarManager: ObservableObject { monthlyManager = MonthlyCalendarManager(configuration: configuration, initialMonth: initialMonth) - pagerManager = ElegantPagesManager(startingPage: 1, + pagesManager = ElegantPagesManager(startingPage: 1, pageTurnType: .calendarEarlySwipe) - pagerManager.delegate = self yearlyManager.communicator = self monthlyManager.communicator = self @@ -78,11 +77,11 @@ public class ElegantCalendarManager: ObservableObject { } -extension ElegantCalendarManager: ElegantPagesDelegate { +extension ElegantCalendarManager { // accounts for both when the user scrolls to the yearly calendar view and the // user presses the month text to scroll to the yearly calendar view - public func elegantPages(willDisplay page: Int) { + func scrollToYearIfOnYearlyView(_ page: Int) { if page == 0 { DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) { self.yearlyManager.scrollToYear(self.currentMonth) @@ -95,7 +94,7 @@ extension ElegantCalendarManager: ElegantPagesDelegate { extension ElegantCalendarManager: ElegantCalendarCommunicator { public func scrollToMonthAndShowMonthlyView(_ month: Date) { - pagerManager.scroll(to: 1) + pagesManager.scroll(to: 1) DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) { self.scrollToMonth(month) @@ -103,7 +102,7 @@ extension ElegantCalendarManager: ElegantCalendarCommunicator { } public func showYearlyView() { - pagerManager.scroll(to: 0) + pagesManager.scroll(to: 0) } } diff --git a/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/MonthlyCalendarManager.swift b/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/MonthlyCalendarManager.swift index 03bc82e..e2d079f 100644 --- a/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/MonthlyCalendarManager.swift +++ b/Sources/ElegantCalendar/Helpers/Models/ObservableObjects/MonthlyCalendarManager.swift @@ -9,7 +9,7 @@ public class MonthlyCalendarManager: ObservableObject, ConfigurationDirectAccess @Published public private(set) var currentMonth: Date @Published public var selectedDate: Date? = nil - let pagerManager: ElegantListManager + let listManager: ElegantListManager @Published public var datasource: MonthlyCalendarDataSource? @Published public var delegate: MonthlyCalendarDelegate? @@ -22,8 +22,6 @@ public class MonthlyCalendarManager: ObservableObject, ConfigurationDirectAccess var allowsHaptics: Bool = true private var isHapticActive: Bool = true - var theme: CalendarTheme = .default - private var anyCancellable: AnyCancellable? public init(configuration: CalendarConfiguration, initialMonth: Date? = nil) { @@ -43,12 +41,8 @@ public class MonthlyCalendarManager: ObservableObject, ConfigurationDirectAccess currentMonth = months[startingPage] - pagerManager = .init(startingPage: startingPage, - pageCount: months.count, - pageTurnType: .monthlyEarlyCutoff) - - pagerManager.datasource = self - pagerManager.delegate = self + listManager = .init(startingPage: startingPage, + pageCount: months.count) anyCancellable = $delegate.sink { $0?.calendar(willDisplayMonth: self.currentMonth) @@ -57,19 +51,9 @@ public class MonthlyCalendarManager: ObservableObject, ConfigurationDirectAccess } -extension MonthlyCalendarManager: ElegantPagesDataSource { - - public func elegantPages(viewForPage page: Int) -> AnyView { - MonthView(calendarManager: self, month: months[page]) - .environment(\.calendarTheme, theme) - .erased - } - -} - -extension MonthlyCalendarManager: ElegantPagesDelegate { +extension MonthlyCalendarManager { - public func elegantPages(willDisplay page: Int) { + func configureNewMonth(at page: Int) { if months[page] != currentMonth { currentMonth = months[page] selectedDate = nil @@ -124,7 +108,7 @@ extension MonthlyCalendarManager { if needsToScroll { let page = calendar.monthsBetween(referenceDate, and: month) - pagerManager.scroll(to: page, animated: animated) + listManager.scroll(to: page, animated: animated) } else { isHapticActive = true } @@ -154,6 +138,14 @@ extension MonthlyCalendarManagerDirectAccess { calendarManager.configuration } + var listManager: ElegantListManager { + calendarManager.listManager + } + + var months: [Date] { + calendarManager.months + } + var communicator: ElegantCalendarCommunicator? { calendarManager.communicator } @@ -174,6 +166,14 @@ extension MonthlyCalendarManagerDirectAccess { calendarManager.selectedDate } + func configureNewMonth(at page: Int) { + calendarManager.configureNewMonth(at: page) + } + + func scrollBackToToday() { + calendarManager.scrollBackToToday() + } + } private extension Calendar { @@ -187,18 +187,3 @@ private extension Calendar { } } - -private extension PageTurnType { - - static var monthlyEarlyCutoff: PageTurnType = .earlyCutoff(config: .monthlyConfig) - -} - -public extension EarlyCutOffConfiguration { - - static let monthlyConfig = EarlyCutOffConfiguration( - scrollResistanceCutOff: 40, - pageTurnCutOff: 80, - pageTurnAnimation: .spring(response: 0.3, dampingFraction: 0.95)) - -} diff --git a/Sources/ElegantCalendar/Helpers/Models/Protocols/Calendar+Buildable.swift b/Sources/ElegantCalendar/Helpers/Models/Protocols/Calendar+Buildable.swift index fb8faf2..3d74a27 100644 --- a/Sources/ElegantCalendar/Helpers/Models/Protocols/Calendar+Buildable.swift +++ b/Sources/ElegantCalendar/Helpers/Models/Protocols/Calendar+Buildable.swift @@ -26,8 +26,9 @@ extension MonthlyCalendarView: Buildable { /// /// - Parameter theme: theme of various components of the calendar public func theme(_ theme: CalendarTheme) -> Self { - calendarManager.theme = theme - calendarManager.pagerManager.reloadPages() + defer { + calendarManager.listManager.reloadPages() + } return mutating(keyPath: \.theme, value: theme) } diff --git a/Sources/ElegantCalendar/Views/ElegantCalendarView.swift b/Sources/ElegantCalendar/Views/ElegantCalendarView.swift index dce54e3..147bfdb 100644 --- a/Sources/ElegantCalendar/Views/ElegantCalendarView.swift +++ b/Sources/ElegantCalendar/Views/ElegantCalendarView.swift @@ -7,17 +7,18 @@ public struct ElegantCalendarView: View { var theme: CalendarTheme = .default - @ObservedObject public var calendarManager: ElegantCalendarManager + public let calendarManager: ElegantCalendarManager public init(calendarManager: ElegantCalendarManager) { self.calendarManager = calendarManager } public var body: some View { - ElegantHPages(manager: calendarManager.pagerManager) { + ElegantHPages(manager: calendarManager.pagesManager) { yearlyCalendarView monthlyCalendarView } + .onPageChanged(calendarManager.scrollToYearIfOnYearlyView) } private var yearlyCalendarView: some View { diff --git a/Sources/ElegantCalendar/Views/Monthly/MonthView.swift b/Sources/ElegantCalendar/Views/Monthly/MonthView.swift index 9a23205..6ed3a4c 100644 --- a/Sources/ElegantCalendar/Views/Monthly/MonthView.swift +++ b/Sources/ElegantCalendar/Views/Monthly/MonthView.swift @@ -39,7 +39,7 @@ struct MonthView: View, MonthlyCalendarManagerDirectAccess { Spacer() } .padding(.top, CalendarConstants.Monthly.topPadding) - .frame(width: CalendarConstants.cellWidth, height: CalendarConstants.cellHeight) + .frame(width: CalendarConstants.Monthly.cellWidth, height: CalendarConstants.cellHeight) } } diff --git a/Sources/ElegantCalendar/Views/Monthly/MonthlyCalendarView.swift b/Sources/ElegantCalendar/Views/Monthly/MonthlyCalendarView.swift index 102d105..00c9236 100644 --- a/Sources/ElegantCalendar/Views/Monthly/MonthlyCalendarView.swift +++ b/Sources/ElegantCalendar/Views/Monthly/MonthlyCalendarView.swift @@ -23,8 +23,21 @@ public struct MonthlyCalendarView: View, MonthlyCalendarManagerDirectAccess { } public var body: some View { - ZStack(alignment: .top) { - monthsList + GeometryReader { geometry in + self.content(geometry: geometry) + } + } + + private func content(geometry: GeometryProxy) -> some View { + CalendarConstants.Monthly.cellWidth = geometry.size.width + + return ZStack(alignment: .top) { + ElegantVList(manager: listManager, + pageTurnType: .monthlyEarlyCutoff, + viewForPage: monthView) + .onPageChanged(configureNewMonth) + .frame(width: CalendarConstants.Monthly.cellWidth) + if isTodayWithinDateRange && !isCurrentMonthYearSameAsTodayMonthYear { leftAlignedScrollBackToTodayButton .padding(.trailing, CalendarConstants.Monthly.outerHorizontalPadding) @@ -32,16 +45,19 @@ public struct MonthlyCalendarView: View, MonthlyCalendarManagerDirectAccess { .transition(.opacity) } } + .frame(height: CalendarConstants.cellHeight) } - private var monthsList: some View { - ElegantVList(manager: calendarManager.pagerManager) + private func monthView(for page: Int) -> AnyView { + MonthView(calendarManager: calendarManager, month: months[page]) + .environment(\.calendarTheme, theme) + .erased } private var leftAlignedScrollBackToTodayButton: some View { HStack { Spacer() - ScrollBackToTodayButton(scrollBackToToday: { self.calendarManager.scrollBackToToday() }, + ScrollBackToTodayButton(scrollBackToToday: scrollBackToToday, color: theme.primary) } } @@ -57,3 +73,18 @@ struct MonthlyCalendarView_Previews: PreviewProvider { } } } + +private extension PageTurnType { + + static var monthlyEarlyCutoff: PageTurnType = .earlyCutoff(config: .monthlyConfig) + +} + +public extension EarlyCutOffConfiguration { + + static let monthlyConfig = EarlyCutOffConfiguration( + scrollResistanceCutOff: 40, + pageTurnCutOff: 80, + pageTurnAnimation: .spring(response: 0.3, dampingFraction: 0.95)) + +} diff --git a/Sources/ElegantCalendar/Views/Yearly/YearView.swift b/Sources/ElegantCalendar/Views/Yearly/YearView.swift index afecf11..4654e8e 100644 --- a/Sources/ElegantCalendar/Views/Yearly/YearView.swift +++ b/Sources/ElegantCalendar/Views/Yearly/YearView.swift @@ -21,7 +21,7 @@ struct YearView: View, YearlyCalendarManagerDirectAccess { Spacer() } .padding(.top, CalendarConstants.Yearly.topPadding) - .frame(width: CalendarConstants.cellWidth, height: CalendarConstants.cellHeight) + .frame(width: CalendarConstants.Yearly.cellWidth, height: CalendarConstants.cellHeight) } private var yearText: some View { diff --git a/Sources/ElegantCalendar/Views/Yearly/YearlyCalendarView.swift b/Sources/ElegantCalendar/Views/Yearly/YearlyCalendarView.swift index 6085afd..25f46f8 100644 --- a/Sources/ElegantCalendar/Views/Yearly/YearlyCalendarView.swift +++ b/Sources/ElegantCalendar/Views/Yearly/YearlyCalendarView.swift @@ -42,7 +42,7 @@ public struct YearlyCalendarView: View, YearlyCalendarManagerDirectAccess { .environment(\.calendarTheme, self.theme) } } - .frame(width: CalendarConstants.cellWidth, + .frame(width: CalendarConstants.Yearly.cellWidth, height: CalendarConstants.cellHeight) }