File tree Expand file tree Collapse file tree 6 files changed +54
-14
lines changed Expand file tree Collapse file tree 6 files changed +54
-14
lines changed Original file line number Diff line number Diff line change 1+ //
2+ // CurrentDateEnvironmentKey.swift
3+ // SwiftUI-Days
4+ //
5+ // Created by Олег Еременко on 27.04.2025.
6+ //
7+
8+ import SwiftUI
9+
10+ private struct CurrentDateKey : EnvironmentKey {
11+ static let defaultValue = Date . now
12+ }
13+
14+ extension EnvironmentValues {
15+ /// Текущая дата, нужна для вычисления количества дней
16+ /// при переходе приложения в активное состояние
17+ ///
18+ /// Например, если свернуть приложение и открыть через пару дней,
19+ /// то количество дней в списке не обновится по умолчанию, а если
20+ /// считать дни по отношению к этой дате, то все будет обновляться
21+ var currentDate : Date {
22+ get { self [ CurrentDateKey . self] }
23+ set { self [ CurrentDateKey . self] = newValue }
24+ }
25+ }
Original file line number Diff line number Diff line change @@ -10,22 +10,22 @@ import SwiftData
1010
1111@Model
1212final class Item {
13- var title : String
14- var details : String
15- var timestamp : Date
16-
17- init ( title: String = " " , details: String = " " , timestamp: Date = . now ) {
13+ var title = " "
14+ var details = " "
15+ var timestamp = Date . now
16+
17+ init ( title: String , details: String = " " , timestamp: Date ) {
1818 self . title = title
1919 self . details = details
2020 self . timestamp = timestamp
2121 }
22-
22+
2323 /// Количество дней с момента события
24- var daysCount : Int {
24+ func makeDaysCount ( to date : Date ) -> Int {
2525 Calendar . current. dateComponents (
2626 [ . day] ,
2727 from: timestamp,
28- to: . now
28+ to: date
2929 ) . day ?? 0
3030 }
3131
Original file line number Diff line number Diff line change 88import SwiftUI
99
1010struct ItemScreen : View {
11+ @Environment ( \. currentDate) private var currentDate
1112 @State private var isEditing = false
1213 let item : Item
1314
@@ -53,7 +54,7 @@ struct ItemScreen: View {
5354 Spacer ( )
5455 }
5556 . padding ( )
56- . navigationTitle ( " \( item. daysCount ) days " )
57+ . navigationTitle ( " \( item. makeDaysCount ( to : currentDate ) ) days " )
5758 . toolbar {
5859 ToolbarItem ( placement: . topBarTrailing) {
5960 DaysEditButton { isEditing. toggle ( ) }
Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ import SwiftData
1010
1111extension MainScreen {
1212 struct ListView : View {
13+ @Environment ( \. currentDate) private var currentDate
1314 @Environment ( \. modelContext) private var modelContext
1415 @Binding private var editItem : Item ?
1516 @Query private var items : [ Item ]
@@ -51,7 +52,8 @@ extension MainScreen {
5152 Text ( item. title)
5253 . lineLimit ( 2 )
5354 . frame ( maxWidth: . infinity, alignment: . leading)
54- Text ( " \( item. daysCount) days " )
55+ Text ( " \( item. makeDaysCount ( to: currentDate) ) days " )
56+ . contentTransition ( . numericText( ) )
5557 . containerRelativeFrame ( . horizontal, alignment: . trailing) { length, _ in
5658 length * 0.3
5759 }
Original file line number Diff line number Diff line change 88import SwiftUI
99
1010struct RootScreen : View {
11+ @Environment ( \. scenePhase) private var scenePhase
1112 @State private var tab = Tab . list
12-
13+ @State private var currentDate = Date . now
14+
1315 var body : some View {
1416 TabView ( selection: $tab) {
1517 ForEach ( Tab . allCases, id: \. self) { tab in
@@ -18,6 +20,13 @@ struct RootScreen: View {
1820 . tag ( tab)
1921 }
2022 }
23+ . environment ( \. currentDate, currentDate)
24+ . animation ( . default, value: currentDate)
25+ . onChange ( of: scenePhase) { _, newPhase in
26+ if newPhase == . active {
27+ currentDate = . now
28+ }
29+ }
2130 }
2231}
2332
Original file line number Diff line number Diff line change @@ -25,7 +25,8 @@ struct SwiftUI_DaysTests {
2525 /// Тестируем `daysCount`, когда событие произошло только что
2626 @Test func daysCountWithNoDaysPassed( ) {
2727 let item = Item ( title: " Recent Event " , timestamp: . now)
28- #expect( item. daysCount == 0 )
28+ let result = item. makeDaysCount ( to: . now)
29+ #expect( result == 0 )
2930 }
3031
3132 /// Тестируем `daysCount` для события, произошедшего 1 день назад
@@ -34,7 +35,8 @@ struct SwiftUI_DaysTests {
3435 title: " One Day Ago " ,
3536 timestamp: Date ( timeIntervalSinceNow: - 86400 )
3637 )
37- #expect( oneDayOldItem. daysCount == 1 )
38+ let result = oneDayOldItem. makeDaysCount ( to: . now)
39+ #expect( result == 1 )
3840 }
3941
4042 /// Тестируем `daysCount` для события, произошедшего 5 дней назад
@@ -43,6 +45,7 @@ struct SwiftUI_DaysTests {
4345 title: " Five Days Ago " ,
4446 timestamp: Date ( timeIntervalSinceNow: - 432000 )
4547 )
46- #expect( fiveDaysOldItem. daysCount == 5 )
48+ let result = fiveDaysOldItem. makeDaysCount ( to: . now)
49+ #expect( result == 5 )
4750 }
4851}
You can’t perform that action at this time.
0 commit comments