Skip to content

Commit 7d2f958

Browse files
authored
#48: Splash экран
1 parent 62fcc99 commit 7d2f958

File tree

8 files changed

+134
-2
lines changed

8 files changed

+134
-2
lines changed

EatHub/EatHub/Application/AppDependencies.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct AppDependencies {
1111

1212
let mealsService: MealsService
1313
let detailsViewModelBuilder: (DetailsViewModuleInput) -> DetailsViewModel
14+
let launchScreenStateManager: LaunchScreenStateManager
1415

1516
init() {
1617
let apiRequester = APIRequester()
@@ -26,6 +27,7 @@ struct AppDependencies {
2627
)
2728
}
2829
self.detailsViewModelBuilder = detailsViewModelBuilder
30+
self.launchScreenStateManager = LaunchScreenStateManager()
2931
}
3032

3133
func makeHomeViewModel() -> HomeViewModel {

EatHub/EatHub/Application/EatHubApp.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ struct EatHubApp: App {
1414

1515
var body: some Scene {
1616
WindowGroup {
17-
MainView(dependencies: dependencies)
17+
ZStack {
18+
MainView(dependencies: dependencies)
19+
if dependencies.launchScreenStateManager.state != .finished {
20+
LaunchScreenView(dependencies: dependencies)
21+
}
22+
}
1823
}
1924
}
2025
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// LaunchScreenStateManager.swift
3+
// EatHub
4+
//
5+
// Created by Даниил Дементьев on 29.03.2025.
6+
//
7+
8+
import Foundation
9+
10+
final class LaunchScreenStateManager: ObservableObject {
11+
12+
@MainActor @Published private(set) var state: LaunchScreenStep = .firstStep
13+
14+
@MainActor func dismiss() {
15+
Task {
16+
state = .secondStep
17+
18+
try? await Task.sleep(for: Duration.seconds(1))
19+
20+
self.state = .finished
21+
}
22+
}
23+
}

EatHub/EatHub/Modules/Home/HomeView.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
//
2+
// HomeView.swift
3+
// EatHub
4+
//
5+
// Created by Даниил Дементьев on 26.03.2025.
6+
//
7+
18
import SwiftUI
29

310
struct HomeView: View {

EatHub/EatHub/Modules/Home/HomeViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// MainViewModal.swift
2+
// HomeViewModal.swift
33
// EatHub
44
//
55
// Created by Даниил Дементьев on 26.03.2025.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//
2+
// LaunchScreenStep.swift
3+
// EatHub
4+
//
5+
// Created by Даниил Дементьев on 29.03.2025.
6+
//
7+
8+
enum LaunchScreenStep {
9+
case firstStep
10+
case secondStep
11+
case finished
12+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//
2+
// LaunchScreenView.swift
3+
// EatHub
4+
//
5+
// Created by Даниил Дементьев on 29.03.2025.
6+
//
7+
8+
import SwiftUI
9+
10+
struct LaunchScreenView: View {
11+
@ObservedObject private var launchScreenStateManager: LaunchScreenStateManager
12+
13+
@State private var firstAnimation = false
14+
@State private var secondAnimation = false
15+
@State private var startFadeoutAnimation = false
16+
17+
init(dependencies: AppDependencies) {
18+
self._launchScreenStateManager = ObservedObject(wrappedValue:
19+
dependencies.launchScreenStateManager)
20+
}
21+
22+
var body: some View {
23+
ZStack {
24+
backgroundColor
25+
image
26+
}.onReceive(animationTimer) { _ in
27+
updateAnimation()
28+
}.opacity(startFadeoutAnimation ? 0 : 1)
29+
}
30+
31+
private var image: some View {
32+
Image(systemName: "fork.knife.circle.fill")
33+
.resizable()
34+
.scaledToFit()
35+
.frame(width: 120, height: 120)
36+
.foregroundStyle(.white)
37+
.rotationEffect(firstAnimation ? .degrees(0) : .degrees(360))
38+
.scaleEffect(secondAnimation ? 0.1 : 1.0)
39+
.offset(y: secondAnimation ? 500 : 0)
40+
.shadow(color: .black.opacity(0.2), radius: 10, x: 0, y: 10)
41+
.animation(.easeInOut(duration: 1.3), value: firstAnimation)
42+
.animation(.easeIn(duration: 0.6), value: secondAnimation)
43+
}
44+
45+
private var backgroundColor: some View {
46+
LinearGradient(
47+
colors: [Color.orange, Color.red],
48+
startPoint: .top,
49+
endPoint: .bottom
50+
)
51+
.ignoresSafeArea()
52+
}
53+
54+
private let animationTimer = Timer
55+
.publish(every: 1.5, on: .current, in: .common)
56+
.autoconnect()
57+
58+
private func updateAnimation() {
59+
switch launchScreenStateManager.state {
60+
case .firstStep:
61+
withAnimation(.easeInOut(duration: 0.9)) {
62+
firstAnimation.toggle()
63+
}
64+
case .secondStep:
65+
if secondAnimation == false {
66+
withAnimation(.linear) {
67+
secondAnimation = true
68+
startFadeoutAnimation = true
69+
}
70+
}
71+
case .finished:
72+
break
73+
}
74+
}
75+
76+
}

EatHub/EatHub/Modules/MainView.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ struct MainView: View {
1111

1212
@State var selectedIndex: MainTabEnum = .home
1313
var dependencies: AppDependencies
14+
private var launchScreenState: LaunchScreenStateManager
1415

1516
init(dependencies: AppDependencies) {
1617
self.dependencies = dependencies
18+
self.launchScreenState = dependencies.launchScreenStateManager
1719
UITabBar.appearance().isHidden = true
1820
}
1921

@@ -33,10 +35,15 @@ struct MainView: View {
3335
MainTabBar(selectedIndex: $selectedIndex)
3436
}
3537
}
38+
.task {
39+
try? await Task.sleep(for: .seconds(2))
40+
launchScreenState.dismiss()
41+
}
3642
}
3743
}
3844

3945
#Preview {
4046
let dependencies = AppDependencies()
47+
let launchScreenState = LaunchScreenStateManager()
4148
return MainView(dependencies: dependencies)
4249
}

0 commit comments

Comments
 (0)