Skip to content

Commit f6364d3

Browse files
committed
Доработал вычисление дней
При разворачивании приложения пересчитываем дни для всех записей по отношении к текущей дате
1 parent 6a7b043 commit f6364d3

File tree

6 files changed

+54
-14
lines changed

6 files changed

+54
-14
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
}

SwiftUI-Days/Models/Item.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@ import SwiftData
1010

1111
@Model
1212
final 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

SwiftUI-Days/Screens/Main/Detail/ItemScreen.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import SwiftUI
99

1010
struct 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() }

SwiftUI-Days/Screens/Main/MainScreen+ListView.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import SwiftData
1010

1111
extension 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
}

SwiftUI-Days/Screens/RootScreen.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import SwiftUI
99

1010
struct 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

SwiftUI-DaysTests/SwiftUI_DaysTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff 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
}

0 commit comments

Comments
 (0)