@@ -9,17 +9,16 @@ import SwiftUI
9
9
10
10
// MARK: - [쿠로] 태그 뷰!
11
11
struct TagView : View {
12
- @State private var popover = false
13
12
@EnvironmentObject private var tagViewModel : TagViewModel
13
+ @State private var popover = false
14
+ @Namespace private var nsPopover
14
15
15
16
var body : some View {
16
17
ZStack ( alignment: . top) {
17
18
Color . gray300
18
19
19
20
GeometryReader { geometry in
20
21
VStack ( spacing: 1 ) {
21
-
22
- // 선택된 태그 화면
23
22
HStack {
24
23
if tagViewModel. isTagSelected {
25
24
SelectedTagView ( )
@@ -36,7 +35,6 @@ struct TagView: View {
36
35
. stroke ( Color . gray400, lineWidth: 1 )
37
36
)
38
37
39
- // 태그 선택하는 화면
40
38
VStack {
41
39
Group {
42
40
if tagViewModel. isTagExist {
@@ -50,12 +48,16 @@ struct TagView: View {
50
48
. frame ( minHeight: geometry. size. height * 0.35 )
51
49
52
50
// 편집 버튼
53
- HStack {
51
+ HStack ( spacing : 0 ) {
54
52
Spacer ( )
55
53
EllipsisView ( ellipsisAction: {
56
- popover. toggle ( )
54
+ withAnimation {
55
+ popover. toggle ( )
56
+ }
57
57
} )
58
- //TODO: - 팝오버 띄우기
58
+ . matchedGeometryEffect ( id: " popover " ,
59
+ in: nsPopover,
60
+ anchor: . topTrailing)
59
61
}
60
62
}
61
63
. frame ( maxWidth: . infinity, maxHeight: geometry. size. height * 0.4 )
@@ -66,28 +68,39 @@ struct TagView: View {
66
68
}
67
69
. padding ( [ . top, . horizontal] , 20 )
68
70
}
71
+ if popover {
72
+ EllipsisButtonView ( namespace: nsPopover)
73
+ . transition ( . opacity. combined ( with: . scale) )
74
+ }
69
75
}
70
76
. frame ( maxWidth: . infinity, maxHeight: . infinity, alignment: . top)
71
77
. ignoresSafeArea ( . all)
78
+ . onTapGesture {
79
+ withAnimation {
80
+ popover = false
81
+ }
82
+ }
72
83
}
73
84
}
74
85
86
+ // MARK: - 태그를 선택하지 않음
75
87
struct TagLEmptyView : View {
76
88
var body : some View {
77
- Text ( " 태그로 원하는 논문을 찾아보세요 " )
78
- . reazyFont ( . button1)
79
- . foregroundStyle ( . gray550)
80
- Spacer ( )
81
- Button ( action: {
82
-
83
- } , label: {
84
- Image ( systemName: " chevron.down " )
85
- . font ( . system( size: 16 ) )
86
- . foregroundStyle ( . gray600)
87
- } )
89
+ Text ( " 태그로 원하는 논문을 찾아보세요 " )
90
+ . reazyFont ( . button1)
91
+ . foregroundStyle ( . gray550)
92
+ Spacer ( )
93
+ Button ( action: {
94
+
95
+ } , label: {
96
+ Image ( systemName: " chevron.down " )
97
+ . font ( . system( size: 16 ) )
98
+ . foregroundStyle ( . gray600)
99
+ } )
88
100
}
89
101
}
90
102
103
+ // MARK: - 태그를 선택함
91
104
struct SelectedTagView : View {
92
105
@EnvironmentObject private var tagViewModel : TagViewModel
93
106
var body : some View {
@@ -103,6 +116,7 @@ struct SelectedTagView: View {
103
116
}
104
117
}
105
118
119
+ // MARK: - 태그 전체 리스트 뷰
106
120
struct TagListView : View {
107
121
@EnvironmentObject private var tagViewModel : TagViewModel
108
122
var body : some View {
@@ -118,6 +132,64 @@ struct TagListView: View {
118
132
}
119
133
}
120
134
135
+ // MARK: - 태그 전체 리스트 뷰
136
+ private struct EllipsisButtonView : View {
137
+ let namespace : Namespace . ID
138
+ var body : some View {
139
+ VStack ( spacing: 0 ) {
140
+ Button {
141
+
142
+ } label: {
143
+ HStack {
144
+ Text ( " 태그 목록 편집 " )
145
+ . reazyFont ( . body1)
146
+ Spacer ( )
147
+ Image ( . editpencil)
148
+ . resizable ( )
149
+ . frame ( width: 17 , height: 17 )
150
+ }
151
+ }
152
+ . foregroundStyle ( . gray800)
153
+ . padding ( . leading, 17 )
154
+ . padding ( . trailing, 14 )
155
+ . padding ( . vertical, 11 )
156
+
157
+ Rectangle ( )
158
+ . foregroundStyle ( . primary2)
159
+ . frame ( height: 1 )
160
+
161
+ Button {
162
+
163
+ } label: {
164
+ HStack {
165
+ Text ( " 새로운 태그 생성 " )
166
+ . reazyFont ( . body1)
167
+ Spacer ( )
168
+ Image ( systemName: " tag " )
169
+ . font ( . system( size: 14 ) )
170
+ }
171
+ }
172
+ . foregroundStyle ( . gray800)
173
+ . padding ( . leading, 17 )
174
+ . padding ( . trailing, 14 )
175
+ . padding ( . vertical, 11 )
176
+ }
177
+ . frame ( width: 200 )
178
+ . background (
179
+ RoundedRectangle ( cornerRadius: 10 )
180
+ . fill ( . gray100)
181
+ . shadow ( color: Color ( hex: " #3C3D4B " ) . opacity ( 0.08 ) , radius: 12 , x: 0 , y: 0 )
182
+ )
183
+ . padding ( . trailing, 70 )
184
+ . matchedGeometryEffect ( id: " popover " ,
185
+ in: namespace,
186
+ properties: . position,
187
+ anchor: . topTrailing,
188
+ isSource: false )
189
+ }
190
+ }
191
+
192
+
121
193
#Preview {
122
194
TagView ( )
123
195
}
0 commit comments