Skip to content

Commit

Permalink
fix #48 add modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
UriyDevyataev committed Mar 14, 2024
1 parent e973620 commit dda7a45
Show file tree
Hide file tree
Showing 2 changed files with 209 additions and 94 deletions.
82 changes: 33 additions & 49 deletions Example/Source/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,58 +55,42 @@ struct MainView: View {
.navigationTitle("SwiftUI presentation")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.sheet(isPresented: $showRangeCalendar) {
self.rangeCalendarView()
}
.sheet(isPresented: $showSingleCalendar) {
self.singleCalendarView()
}
}

private func rangeCalendarView() -> some View {
let config: FastisConfig = .default
var fastisView = FastisView(mode: .range, config: config)
fastisView.title = "Choose range"
fastisView.initialValue = self.currentValue as? FastisRange
fastisView.minimumDate = Calendar.current.date(byAdding: .month, value: -2, to: Date())
fastisView.maximumDate = Calendar.current.date(byAdding: .month, value: 3, to: Date())
fastisView.allowToChooseNilDate = true
fastisView.allowDateRangeChanges = false
fastisView.shortcuts = [.lastWeek, .lastMonth]
fastisView.selectMonthOnHeaderTap = true

fastisView.dismissHandler = { action in
switch action {
case .done(let newValue):
self.currentValue = newValue
case .cancel:
print("any actions")
FastisView(mode: .range) { action in
switch action {
case .done(let newValue):
self.currentValue = newValue
case .cancel:
print("any actions")
}
}
.title("Choose range")
.initialValue(self.currentValue as? FastisRange)
.minimumDate(Calendar.current.date(byAdding: .month, value: -2, to: Date()))
.maximumDate(Calendar.current.date(byAdding: .month, value: 3, to: Date()))
.allowToChooseNilDate(true)
.allowDateRangeChanges(false)
.shortcuts([.lastWeek, .lastMonth])
.selectMonthOnHeaderTap(true)
.ignoresSafeArea()
}
return fastisView.ignoresSafeArea()
}

private func singleCalendarView() -> some View {
let config: FastisConfig = .default
var fastisView = FastisView(mode: .single, config: config)
fastisView.title = "Choose date"
fastisView.initialValue = self.currentValue as? Date
fastisView.minimumDate = Calendar.current.date(byAdding: .month, value: -2, to: Date())
fastisView.maximumDate = Date()
fastisView.allowToChooseNilDate = true
fastisView.allowDateRangeChanges = false
fastisView.shortcuts = [.yesterday, .today, .tomorrow]
fastisView.closeOnSelectionImmediately = true

fastisView.dismissHandler = { action in
switch action {
case .done(let newValue):
self.currentValue = newValue
case .cancel:
print("any actions")
.sheet(isPresented: $showSingleCalendar) {
FastisView(mode: .single) { action in
switch action {
case .done(let newValue):
self.currentValue = newValue
case .cancel:
print("any actions")
}
}
.title("Choose date")
.initialValue(self.currentValue as? Date)
.minimumDate(Calendar.current.date(byAdding: .month, value: -2, to: Date()))
.maximumDate(Date())
.allowToChooseNilDate(true)
.allowDateRangeChanges(false)
.shortcuts([.yesterday, .today, .tomorrow])
.closeOnSelectionImmediately(true)
.ignoresSafeArea()
}
return fastisView.ignoresSafeArea()
}

}

221 changes: 176 additions & 45 deletions Sources/Views/FastisView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,76 +12,128 @@ import SwiftUI
View of Fastis framework. Use it to create and present dade picker

Usage example:
```swift
let fastisView = FastisView(mode: .range)
fastisView.title = "Choose range"
fastisView.maximumDate = Date()
fastisView.allowToChooseNilDate = true
fastisView.shortcuts = [.today, .lastWeek]
fastisView.dismissHandler = { [weak self] action in
switch action {
case .done(let newValue):
...
case .cancel:
...
}
```swiftUI
FastisView(mode: .range) { action in
switch action {
case .done(let newValue):
...
case .cancel:
...
}
}
.title = "Choose range"
.maximumDate = Date()
.allowToChooseNilDate = true
.shortcuts = [.today, .lastWeek]
```

**Single and range modes**

If you want to get a single date you have to use `Date` type:

```swift
let fastisView = FastisView(mode: .single)
fastisView.initialValue = Date()
fastisView.closeOnSelectionImmediately = true
fastisView.dismissHandler = { [weak self] action in
switch action {
case .done(let resultDate):
print(resultDate) // resultDate is Date
case .cancel:
...
}
}
```swiftUI
FastisView(mode: .single) { action in
switch action {
case .done(let resultDate):
print(resultDate) // resultDate is Date
case .cancel:
...
}
}
.initialValue = Date()
.closeOnSelectionImmediately = true
```

If you want to get a date range you have to use `FastisRange` type:

```swift
let fastisView = FastisView(mode: .range)
fastisView.initialValue = FastisRange(from: Date(), to: Date()) // or .from(Date(), to: Date())
fastisView.dismissHandler = { [weak self] action in
switch action {
case .done(let resultRange):
print(resultRange) // resultRange is FastisRange
case .cancel:
...
}
```swiftUI
FastisView(mode: .range) { action in
switch action {
case .done(let resultRange):
print(resultRange) // resultRange is FastisRange
case .cancel:
...
}
}
.initialValue = FastisRange(from: Date(), to: Date()) // or .from(Date(), to: Date())
```
*/

public struct FastisView<Value: FastisValue>: UIViewControllerRepresentable {

private var privateSelectMonthOnHeaderTap = false
private var privateCloseOnSelectionImmediately = false
private let config: FastisConfig

/**
And title controller
*/
public var title: String? = nil

/**
And initial value which will be selected by default
*/
public var initialValue: Value? = nil

/**
Minimal selection date. Dates less then current will be marked as unavailable
*/
public var minimumDate: Date? = nil

/**
Maximum selection date. Dates greater then current will be marked as unavailable
*/
public var maximumDate: Date? = nil

/**
Allow to choose `nil` date

When `allowToChooseNilDate` is `true`:
* "Done" button will be always enabled
* You will be able to reset selection by you tapping on selected date again
*/
public var allowToChooseNilDate: Bool = false

/**
Allow date range changes

Set this variable to `false` if you want to disable date range changes.
Next tap after selecting range will start new range selection.
*/
public var allowDateRangeChanges: Bool = true
public var shortcuts: [FastisShortcut<Value>] = []
public var dismissHandler: ((FastisController<Value>.DismissAction) -> Void)? = nil

private var privateSelectMonthOnHeaderTap = false
private var privateCloseOnSelectionImmediately = false
/**
Shortcuts array

private let config: FastisConfig
You can use prepared shortcuts depending on the current mode.

- For `.single` mode: `.today`, `.tomorrow`, `.yesterday`
- For `.range` mode: `.today`, `.lastWeek`, `.lastMonth`

Or you can create your own shortcuts:

```
var customShortcut = FastisShortcut(name: "Today") {
let now = Date()
return FastisRange(from: now.startOfDay(), to: now.endOfDay())
}
```
*/
public var shortcuts: [FastisShortcut<Value>] = []

/**
The block to execute after the dismissal finishes, return two variable .done(FastisValue?) and .cancel
*/
public var dismissHandler: ((FastisController<Value>.DismissAction) -> Void)? = nil

/// Initiate FastisView
/// - Parameter config: Configuration parameters
init(config: FastisConfig = .default) {
public init(
config: FastisConfig = .default,
dismissHandler: ((FastisController<Value>.DismissAction) -> Void)? = nil
) {
self.config = config
self.dismissHandler = dismissHandler
}

public func makeUIViewController(context: Context) -> UINavigationController {
Expand Down Expand Up @@ -117,8 +169,12 @@ public extension FastisView where Value == FastisRange {
/// - Parameters:
/// - mode: Choose `.range` or `.single` mode
/// - config: Custom configuration parameters. Default value is equal to `FastisConfig.default`
init(mode: FastisModeRange, config: FastisConfig = .default) {
self.init(config: config)
init(
mode: FastisModeRange,
config: FastisConfig = .default,
dismissHandler: ((FastisController<Value>.DismissAction) -> Void)? = nil
) {
self.init(config: config, dismissHandler: dismissHandler)
}

/**
Expand All @@ -140,8 +196,12 @@ public extension FastisView where Value == Date {
/// - Parameters:
/// - mode: Choose .range or .single mode
/// - config: Custom configuration parameters. Default value is equal to `FastisConfig.default`
init(mode: FastisModeSingle, config: FastisConfig = .default) {
self.init(config: config)
init(
mode: FastisModeSingle,
config: FastisConfig = .default,
dismissHandler: ((FastisController<Value>.DismissAction) -> Void)? = nil
) {
self.init(config: config, dismissHandler: dismissHandler)
}

/**
Expand All @@ -159,3 +219,74 @@ public extension FastisView where Value == Date {
}
}

public extension FastisView {

/// Modifier for property 'title'
func title(_ value: String?) -> FastisView<Value> {
var view = self
view.title = value
return view
}

/// Modifier for property 'initialValue'
func initialValue(_ value: Value?) -> FastisView<Value> {
var view = self
view.initialValue = value
return view
}

/// Modifier for property 'minimumDate'
func minimumDate(_ value: Date?) -> FastisView<Value> {
var view = self
view.minimumDate = value
return view
}

/// Modifier for property 'maximumDate'
func maximumDate(_ value: Date?) -> FastisView<Value> {
var view = self
view.maximumDate = value
return view
}

/// Modifier for property 'allowToChooseNilDate'
func allowToChooseNilDate(_ value: Bool) -> FastisView<Value> {
var view = self
view.allowToChooseNilDate = value
return view
}

/// Modifier for property 'allowDateRangeChanges'
func allowDateRangeChanges(_ value: Bool) -> FastisView<Value> {
var view = self
view.allowDateRangeChanges = value
return view
}

/// Modifier for property 'shortcuts'
func shortcuts(_ value: [FastisShortcut<Value>]) -> FastisView<Value> {
var view = self
view.shortcuts = value
return view
}
}

public extension FastisView where Value == FastisRange {

/// Modifier for property 'selectMonthOnHeaderTap'
func selectMonthOnHeaderTap(_ value: Bool) -> FastisView<Value> {
var view = self
view.selectMonthOnHeaderTap = value
return view
}
}

public extension FastisView where Value == Date {

/// Modifier for property 'closeOnSelectionImmediately'
func closeOnSelectionImmediately(_ value: Bool) -> FastisView<Value> {
var view = self
view.closeOnSelectionImmediately = value
return view
}
}

0 comments on commit dda7a45

Please sign in to comment.