@@ -2,20 +2,38 @@ import SwiftUI
2
2
3
3
struct FavoriteView : View {
4
4
@ObservedObject var viewModel : FavoriteViewModel
5
+ @State private var selectedItem : RecipeViewModel ?
6
+ @State private var showDetail : Bool = false
7
+ @Namespace private var animationNamespace
8
+
9
+ private enum Constants {
10
+ static let animationDuration : TimeInterval = 0.5
11
+ static let detailZIndex : Double = 1
12
+ static let detailTransition : AnyTransition = . asymmetric(
13
+ insertion: . move( edge: . bottom) ,
14
+ removal: . move( edge: . bottom)
15
+ )
16
+ }
5
17
6
18
var body : some View {
7
19
NavigationView {
8
- ScrollView {
9
- VStack ( alignment: . leading, spacing: 0 ) {
10
- favoritesTitle
11
- favoritesList
20
+ ZStack {
21
+ ScrollView {
22
+ VStack ( alignment: . leading, spacing: 0 ) {
23
+ favoritesTitle
24
+ favoritesList
25
+ }
26
+ }
27
+ . background ( Color ( . systemGroupedBackground) )
28
+ . onAppear {
29
+ viewModel. refreshFavorites ( )
30
+ }
31
+
32
+ if let selectedItem, showDetail {
33
+ openDetailsView ( for: selectedItem)
12
34
}
13
35
}
14
- . background ( Color ( . systemGroupedBackground) )
15
36
. navigationBarHidden ( true )
16
- . onAppear {
17
- viewModel. refreshFavorites ( )
18
- }
19
37
}
20
38
}
21
39
}
@@ -30,20 +48,48 @@ private extension FavoriteView {
30
48
31
49
var favoritesList : some View {
32
50
LazyVStack ( spacing: 8 ) {
33
- ForEach ( viewModel. likedRecipes) { recipe in
34
- // TODO: Добавить переход
35
- // NavigationLink(destination: RecipeDetailView(recipe: recipe)) {
51
+ ForEach ( viewModel. likedRecipes) { recipeViewModel in
36
52
RecipeRow (
37
- recipe: recipe ,
53
+ recipe: recipeViewModel ,
38
54
onToggleFavorite: {
39
- viewModel. toggleFavorite ( for: recipe )
55
+ viewModel. toggleFavorite ( for: recipeViewModel )
40
56
}
41
57
)
42
- // }
43
- . buttonStyle ( PlainButtonStyle ( ) )
58
+ . onTapGesture {
59
+ withAnimation ( . easeInOut( duration: Constants . animationDuration) ) {
60
+ selectedItem = recipeViewModel
61
+ showDetail = true
62
+ }
63
+ }
44
64
}
45
65
}
46
66
. padding ( . horizontal)
47
67
. padding ( . top, 8 )
48
68
}
69
+
70
+ @ViewBuilder
71
+ func openDetailsView( for recipeViewModel: RecipeViewModel ) -> some View {
72
+ let viewModel = viewModel. detailsViewModelBuilder (
73
+ DetailsViewModuleInput (
74
+ id: recipeViewModel. id,
75
+ name: recipeViewModel. name,
76
+ thumbnail: recipeViewModel. thumbnail
77
+ )
78
+ )
79
+ DetailsView (
80
+ viewModel: viewModel,
81
+ onClose: {
82
+ withAnimation ( . easeInOut( duration: Constants . animationDuration) ) {
83
+ showDetail = false
84
+ viewModel. isCloseButtonHidden = true
85
+ }
86
+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + Constants. animationDuration) {
87
+ selectedItem = nil
88
+ }
89
+ } ,
90
+ namespace: animationNamespace
91
+ )
92
+ . zIndex ( Constants . detailZIndex)
93
+ . transition ( Constants . detailTransition)
94
+ }
49
95
}
0 commit comments