Skip to content

Commit 3587e03

Browse files
committed
setup FXDatePicker
1 parent a37e220 commit 3587e03

11 files changed

+547
-30
lines changed

Package.swift

+19-18
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
5+
6+
let package = Package(
7+
name: "FXDatePicker",
8+
platforms: [
9+
.iOS(.v14) // Specifies that the package requires iOS 13.0 or newer
10+
],
11+
products: [
12+
// Products define the executables and libraries a package produces, making them visible to other packages.
13+
.library(
14+
name: "FXDatePicker",
15+
targets: ["FXDatePicker"]),
16+
],
17+
targets: [
18+
// Targets are the basic building blocks of a package, defining a module or a test suite.
19+
// Targets can depend on other targets in this package and products from dependencies.
20+
.target(
21+
name: "FXDatePicker")
22+
]
23+
)
524

6-
let package = Package(
7-
name: "FXDatePicker",
8-
products: [
9-
// Products define the executables and libraries a package produces, making them visible to other packages.
10-
.library(
11-
name: "FXDatePicker",
12-
targets: ["FXDatePicker"]),
13-
],
14-
targets: [
15-
// Targets are the basic building blocks of a package, defining a module or a test suite.
16-
// Targets can depend on other targets in this package and products from dependencies.
17-
.target(
18-
name: "FXDatePicker"),
19-
.testTarget(
20-
name: "FXDatePickerTests",
21-
dependencies: ["FXDatePicker"]),
22-
]
23-
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
////
2+
//SpecialDate.swift
3+
//DatePickerExample
4+
//
5+
//Created by Basel Baragabah on 01/01/2024.
6+
//Copyright © 2024 Basel Baragabah. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import SwiftUI
11+
12+
public struct SpecialDate {
13+
var dateType: SpecialDateType
14+
}
15+
16+
public enum SpecialDateType {
17+
case image(ImageType)
18+
case sfSymbols(SFSymbolsType)
19+
}
20+
21+
public struct ImageType {
22+
var dateString: String
23+
var imageName: String
24+
}
25+
26+
public struct SFSymbolsType {
27+
var dateString: String
28+
var imageName: String
29+
var color: Color
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
////
2+
//SwiftUIView.swift
3+
//
4+
//
5+
//Created by Basel Baragabah on 01/01/2024.
6+
//Copyright © 2024 Basel Baragabah. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
public extension Color {
12+
init(color: UIColor) {
13+
if #available(iOS 15.0, *) {
14+
self.init(uiColor: color)
15+
} else {
16+
let ciColor = CIColor(color: color)
17+
self.init(red: Double(ciColor.red), green: Double(ciColor.green), blue: Double(ciColor.blue), opacity: Double(ciColor.alpha))
18+
}
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
////
2+
//String+Ext.swift
3+
//DatePickerExample
4+
//
5+
//Created by Basel Baragabah on 01/01/2024.
6+
//Copyright © 2024 Basel Baragabah. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
public extension String {
12+
func dateFromString(calendar: Calendar) -> Date? {
13+
let dateFormatter = DateFormatter()
14+
dateFormatter.calendar = calendar
15+
dateFormatter.dateFormat = "dd/MM/yyyy"
16+
return dateFormatter.date(from: self)
17+
}
18+
19+
func toHijri() -> String? {
20+
let dateFormatter = DateFormatter()
21+
dateFormatter.calendar = Calendar(identifier: .gregorian)
22+
dateFormatter.dateFormat = "dd/MM/yyyy"
23+
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
24+
25+
if let date = dateFormatter.date(from: self) {
26+
dateFormatter.calendar = Calendar(identifier: .islamicUmmAlQura)
27+
return dateFormatter.string(from: date)
28+
}
29+
return nil
30+
}
31+
32+
func toGregorian() -> String? {
33+
let dateFormatter = DateFormatter()
34+
dateFormatter.calendar = Calendar(identifier: .islamicUmmAlQura)
35+
dateFormatter.dateFormat = "dd/MM/yyyy"
36+
37+
if let date = dateFormatter.date(from: self) {
38+
dateFormatter.calendar = Calendar(identifier: .gregorian)
39+
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
40+
return dateFormatter.string(from: date)
41+
}
42+
return nil
43+
}
44+
45+
46+
}
47+
48+
49+
50+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
////
2+
//SwiftUIView.swift
3+
//
4+
//
5+
//Created by Basel Baragabah on 01/01/2024.
6+
//Copyright © 2024 Basel Baragabah. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
extension View {
12+
@ViewBuilder func toBold(_ condition: Bool = true) -> some View {
13+
if condition {
14+
if #available(iOS 16.0, *) {
15+
self.bold() // New method available in iOS 16
16+
} else {
17+
// Alternative for older versions
18+
self.font(Font.body.bold())
19+
}
20+
}
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
////
2+
//CalenderType.swift
3+
//DatePickerExample
4+
//
5+
//Created by Basel Baragabah on 01/01/2024.
6+
//Copyright © 2024 Basel Baragabah. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
public enum CalenderType {
12+
case gregorian
13+
case hijri
14+
}
15+
16+
public struct CalenderTypeModifier: ViewModifier {
17+
var calenderType: CalenderType
18+
19+
public func body(content: Content) -> some View {
20+
content
21+
.environment(\.calenderType, calenderType)
22+
}
23+
}
24+
25+
public struct CalenderTypeKey: EnvironmentKey {
26+
public static let defaultValue: CalenderType = .gregorian
27+
}
28+
29+
public extension EnvironmentValues {
30+
var calenderType: CalenderType {
31+
get { self[CalenderTypeKey.self] }
32+
set { self[CalenderTypeKey.self] = newValue }
33+
}
34+
}
35+
36+
public extension View {
37+
func calenderType(_ type: CalenderType) -> some View {
38+
self.modifier(CalenderTypeModifier(calenderType: type))
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
////
2+
//ThemeColorModifier.swift
3+
//DatePickerExample
4+
//
5+
//Created by Basel Baragabah on 01/01/2024.
6+
//Copyright © 2024 Basel Baragabah. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
@available(iOS 14.0, *)
12+
public struct DatePickerThemeKey: EnvironmentKey {
13+
public static var defaultValue: DatePickerTheme = DatePickerTheme()
14+
}
15+
16+
public extension EnvironmentValues {
17+
var datePickerTheme: DatePickerTheme {
18+
get { self[DatePickerThemeKey.self] }
19+
set { self[DatePickerThemeKey.self] = newValue }
20+
}
21+
}
22+
23+
public extension View {
24+
func datePickerTheme(_ theme: DatePickerTheme) -> some View {
25+
self.environment(\.datePickerTheme, theme)
26+
}
27+
28+
func datePickerTheme(
29+
main: DatePickerTheme.Main = .init()
30+
) -> some View {
31+
self.environment(\.datePickerTheme, DatePickerTheme(main: main))
32+
}
33+
}
34+
35+
public struct DatePickerTheme {
36+
public let main: Main
37+
38+
public init(main: DatePickerTheme.Main = .init()) {
39+
self.main = main
40+
}
41+
}
42+
43+
public extension DatePickerTheme {
44+
struct Main {
45+
public let accentColor: Color
46+
public let monthTitle: Color
47+
public let daysName: Color
48+
public let daysNumbers: Color
49+
public let previousDaysNumber: Color
50+
public let backgroundColor: Color
51+
52+
public init(accentColor: Color = .blue,
53+
monthTitle: Color = Color(color: .label),
54+
daysName: Color = .gray,
55+
daysNumbers: Color = Color(color: .label),
56+
previousDaysNumber: Color = .gray,
57+
backgroundColor: Color = Color(color: .systemBackground)) {
58+
59+
self.accentColor = accentColor
60+
self.monthTitle = monthTitle
61+
self.daysName = daysName
62+
self.daysNumbers = daysNumbers
63+
self.previousDaysNumber = previousDaysNumber
64+
self.backgroundColor = backgroundColor
65+
66+
}
67+
}
68+
}
69+
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
////
2+
//DayView.swift
3+
//DatePickerExample
4+
//
5+
//Created by Basel Baragabah on 01/01/2024.
6+
//Copyright © 2024 Basel Baragabah. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
@available(iOS 14.0, *)
12+
public struct DayView: View {
13+
let date: Date?
14+
let isSelected: Bool
15+
let isBeforeToday: Bool
16+
let isToday: Bool
17+
let specialDate: SpecialDate?
18+
private let imageSize: CGFloat = 25
19+
let calendar: Calendar
20+
21+
@Environment(\.calenderType) private var calenderType
22+
@Environment(\.datePickerTheme) private var theme
23+
24+
public var body: some View {
25+
VStack(spacing: 0) {
26+
if let date = date {
27+
Text(dayFormatter.string(from: date))
28+
.foregroundColor(isSelected ?
29+
(isToday ? .white : theme.main.accentColor) :
30+
(isBeforeToday ? theme.main.previousDaysNumber :
31+
(isToday ? theme.main.accentColor :
32+
theme.main.daysNumbers)))
33+
.font(.system(size: 20))
34+
.toBold(isSelected || isToday)
35+
.frame(width: 30, height: 30)
36+
.padding(.horizontal, 8)
37+
.background(isSelected ? isToday ? theme.main.accentColor : theme.main.accentColor.opacity(0.2) : Color.clear)
38+
.cornerRadius(20)
39+
}
40+
41+
ZStack {
42+
43+
if let specialDate = specialDate {
44+
specialDateImage(specialDate)
45+
}
46+
47+
Spacer()
48+
}
49+
.frame(height: imageSize)
50+
}
51+
.frame(height: 70) // height for DayView
52+
}
53+
54+
@ViewBuilder func specialDateImage(_ specialDate: SpecialDate) -> some View {
55+
switch specialDate.dateType {
56+
case .image(let imageType):
57+
58+
Image(imageType.imageName)
59+
.resizable()
60+
.scaledToFit()
61+
62+
case .sfSymbols(let sfSymbolsType):
63+
Image(systemName: sfSymbolsType.imageName)
64+
.foregroundColor(sfSymbolsType.color)
65+
66+
}
67+
}
68+
69+
70+
private var dayFormatter: DateFormatter {
71+
let formatter = DateFormatter()
72+
formatter.calendar = calendar
73+
formatter.dateFormat = "d"
74+
formatter.locale = Locale(identifier: Locale.preferredLanguages.first ?? "ar")
75+
return formatter
76+
}
77+
}
78+
79+

0 commit comments

Comments
 (0)