@@ -11,56 +11,83 @@ struct SearchBarView: View {
1111 @Binding var searchText : String
1212 @FocusState private var isFocused : Bool
1313 @State private var showCancel : Bool = false
14+ @State private var containerHeight : CGFloat = 50
15+ @Environment ( \. dynamicTypeSize) private var dynamicTypeSize
1416
17+ private func recomputeHeight( ) {
18+ // Use a Dynamic Type–aware font close to .ico14 (subheadline ~ 15pt)
19+ let lineHeight = UIFont . preferredFont ( forTextStyle: . subheadline) . lineHeight
20+ // Vertical paddings used below are 14(top)+14(bottom) = 28
21+ let calculated = lineHeight + 28
22+ // Ensure minimum tap target
23+ containerHeight = max ( 44 , calculated)
24+ }
25+
1526 var body : some View {
16- HStack ( spacing: 0 ) {
17- HStack {
18- Image ( systemName: " magnifyingglass " )
19- . foregroundStyle ( . iCoLabel)
20-
21- TextField ( " 코인 이름으로 검색하세요 " , text: $searchText)
22- . keyboardType ( . webSearch)
23- . textInputAutocapitalization ( . never)
24- . autocorrectionDisabled ( true )
25- . padding ( . horizontal, 8 )
26- . submitLabel ( . search)
27- . font ( . system( size: 14 ) )
28- . focused ( $isFocused)
29- . onChange ( of: isFocused) {
30- showCancel = isFocused
31- }
32-
33- if !searchText. isEmpty {
34- CircleDeleteButton ( fontSize: 9 ) {
35- searchText = " "
27+ GeometryReader { proxy in
28+ HStack ( spacing: 0 ) {
29+ HStack {
30+ Image ( systemName: " magnifyingglass " )
31+ . foregroundStyle ( . iCoLabel)
32+
33+ TextField ( " 코인 이름으로 검색하세요 " , text: $searchText)
34+ . keyboardType ( . webSearch)
35+ . textInputAutocapitalization ( . never)
36+ . autocorrectionDisabled ( true )
37+ . padding ( . horizontal, 8 )
38+ . submitLabel ( . search)
39+ . font ( . ico14)
40+ . focused ( $isFocused)
41+ . onChange ( of: isFocused) {
42+ showCancel = isFocused
43+ }
44+
45+ if !searchText. isEmpty {
46+ CircleDeleteButton ( fontSize: 9 ) {
47+ print ( " Tapped " )
48+ searchText = " "
49+ }
3650 }
3751 }
38- }
39- . padding ( . horizontal , 12 )
40- . padding ( . vertical , 14 )
41- . background {
42- RoundedRectangle ( cornerRadius : 15 )
43- . fill ( showCancel ? . iCoBackgroundBlue : . iCoBackground )
44- }
45- . overlay {
46- RoundedRectangle ( cornerRadius : 15 )
47- . strokeBorder ( showCancel ? . accentGradient : . defaultGradient , lineWidth : 0.5 )
48- }
49-
50- Button {
52+ . padding ( . horizontal , 12 )
53+ . padding ( . vertical , 14 )
54+ . background {
55+ RoundedRectangle ( cornerRadius : 15 )
56+ . fill ( showCancel ? . iCoBackgroundBlue : . iCoBackground )
57+ }
58+ . overlay {
59+ RoundedRectangle ( cornerRadius : 15 )
60+ . strokeBorder ( showCancel ? . accentGradient : . defaultGradient , lineWidth : 0.5 )
61+ }
62+ . animation ( . bouncy , value : showCancel )
63+
64+ Button {
5165 isFocused = false
5266 searchText = " "
53- } label: {
54- Text ( " 취소 " )
55- . foregroundStyle ( . iCoNegative)
56- . font ( . system( size: 13 ) )
67+ } label: {
68+ Text ( " 취소 " )
69+ . foregroundStyle ( . iCoNegative)
70+ . font ( . ico13)
71+ }
72+ . opacity ( showCancel ? 1 : 0 )
73+ . frame ( width: showCancel ? 40 : 0 , alignment: . trailing)
74+ . animation ( . default, value: showCancel)
5775 }
58- . opacity ( showCancel ? 1 : 0 )
59- . frame ( width: showCancel ? 40 : 0 , alignment: . trailing)
60- . animation ( nil , value: showCancel)
6176 }
77+ . frame ( height: containerHeight)
78+ . onAppear { recomputeHeight ( ) }
79+ . onChange ( of: dynamicTypeSize, { oldValue, newValue in
80+ recomputeHeight ( )
81+ } )
6282 . onTapGesture {
6383 isFocused = true
6484 }
6585 }
6686}
87+
88+ #Preview( traits: . sizeThatFitsLayout) {
89+ @Previewable @State var searchText : String = " key "
90+ SearchBarView ( searchText: $searchText)
91+ . padding ( )
92+ . frame ( width: . infinity, height: 100 )
93+ }
0 commit comments