@@ -17,35 +17,35 @@ public protocol FloatingLabelTextFieldStyle {
17
17
//MARK: FloatingLabelTextField View
18
18
@available ( iOS 13 . 0 , * )
19
19
public struct FloatingLabelTextField : View {
20
-
20
+
21
21
//MARK: Binding Property
22
22
@Binding private var textFieldValue : String
23
- @State fileprivate var isSelected : Bool = false
23
+ @State var isSelected : Bool = false
24
24
@Binding private var validtionChecker : Bool
25
-
25
+
26
26
private var currentError : TextFieldValidator {
27
27
if notifier. isRequiredField && isShowError && textFieldValue. isEmpty {
28
28
return TextFieldValidator ( condition: false , errorMessage: notifier. requiredFieldMessage)
29
29
}
30
-
30
+
31
31
if let firstError = notifier. arrValidator. filter ( { !$0. condition} ) . first {
32
32
return firstError
33
33
}
34
34
return TextFieldValidator ( condition: true , errorMessage: " " )
35
35
}
36
-
37
- @State fileprivate var isShowError : Bool = false
38
-
36
+
37
+ @State var isShowError : Bool = false
38
+
39
39
@State fileprivate var isFocused : Bool = false
40
-
40
+
41
41
//MARK: Observed Object
42
42
@ObservedObject private var notifier = FloatingLabelTextFieldNotifier ( )
43
-
43
+
44
44
//MARK: Properties
45
45
private var placeholderText : String = " "
46
46
private var editingChanged : ( Bool ) -> ( ) = { _ in }
47
47
private var commit : ( ) -> ( ) = { }
48
-
48
+
49
49
//MARK: Init
50
50
public init ( _ text: Binding < String > , validtionChecker: Binding < Bool > ? = nil , placeholder: String = " " , editingChanged: @escaping ( Bool ) -> ( ) = { _ in } , commit: @escaping ( ) -> ( ) = { } ) {
51
51
self . _textFieldValue = text
@@ -54,18 +54,18 @@ public struct FloatingLabelTextField: View {
54
54
self . commit = commit
55
55
self . _validtionChecker = validtionChecker ?? Binding . constant ( false )
56
56
}
57
-
57
+
58
58
// MARK: Center View
59
59
var centerTextFieldView : some View {
60
60
ZStack ( alignment: notifier. textAlignment. getAlignment ( ) ) {
61
-
61
+
62
62
if ( notifier. isAnimateOnFocus ? ( !isSelected && textFieldValue. isEmpty) : textFieldValue. isEmpty) {
63
63
Text ( placeholderText)
64
64
. font ( notifier. placeholderFont)
65
65
. multilineTextAlignment ( notifier. textAlignment)
66
66
. foregroundColor ( notifier. placeholderColor)
67
67
}
68
-
68
+
69
69
if notifier. isSecureTextEntry {
70
70
SecureField ( " " , text: $textFieldValue. animation ( ) ) {
71
71
}
@@ -97,13 +97,13 @@ public struct FloatingLabelTextField: View {
97
97
. font ( notifier. font)
98
98
. multilineTextAlignment ( notifier. textAlignment)
99
99
. foregroundColor ( ( self . currentError. condition || !notifier. isShowError) ? ( isSelected ? notifier. selectedTextColor : notifier. textColor) : notifier. errorColor)
100
-
100
+
101
101
} else {
102
102
TextField ( " " , text: $textFieldValue. animation ( ) , onEditingChanged: { ( isChanged) in
103
103
withAnimation {
104
104
self . isSelected = isChanged
105
105
}
106
-
106
+
107
107
self . validtionChecker = self . currentError. condition
108
108
self . editingChanged ( isChanged)
109
109
self . isShowError = self . notifier. isRequiredField
@@ -122,7 +122,7 @@ public struct FloatingLabelTextField: View {
122
122
}
123
123
}
124
124
}
125
-
125
+
126
126
// MARK: Top error and title lable view
127
127
var topTitleLable : some View {
128
128
Text ( ( self . currentError. condition || !notifier. isShowError) ? placeholderText : self . currentError. errorMessage)
@@ -131,48 +131,48 @@ public struct FloatingLabelTextField: View {
131
131
. foregroundColor ( ( self . currentError. condition || !notifier. isShowError) ? ( self . isSelected ? notifier. selectedTitleColor : notifier. titleColor) : notifier. errorColor)
132
132
. font ( notifier. titleFont)
133
133
}
134
-
134
+
135
135
// MARK: Bottom Line View
136
136
var bottomLine : some View {
137
137
Divider ( )
138
138
. frame ( height: self . isSelected ? notifier. selectedLineHeight : notifier. lineHeight, alignment: . leading)
139
139
}
140
-
140
+
141
141
//MARK: Body View
142
142
public var body : some View {
143
143
VStack ( ) {
144
144
ZStack ( alignment: . bottomLeading) {
145
-
145
+
146
146
//Top error and title lable view
147
147
if notifier. isShowError && self . isShowError && textFieldValue. isEmpty || ( notifier. isAnimateOnFocus && isSelected) {
148
148
self . topTitleLable. padding ( . bottom, CGFloat ( notifier. spaceBetweenTitleText) ) . opacity ( 1 )
149
-
149
+
150
150
} else {
151
151
self . topTitleLable. padding ( . bottom, CGFloat ( !textFieldValue. isEmpty ? notifier. spaceBetweenTitleText : 0 ) ) . opacity ( ( textFieldValue. isEmpty) ? 0 : 1 )
152
152
}
153
-
153
+
154
154
HStack {
155
155
// Left View
156
156
notifier. leftView
157
-
157
+
158
158
// Center View
159
159
centerTextFieldView
160
-
160
+
161
161
//Right View
162
162
notifier. rightView
163
163
}
164
164
}
165
-
165
+
166
166
//MARK: Line View
167
167
if textFieldValue. isEmpty || !notifier. isShowError {
168
168
bottomLine
169
169
. background ( ( self . isSelected ? notifier. selectedLineColor : notifier. lineColor) )
170
-
170
+
171
171
} else {
172
172
bottomLine
173
173
. background ( ( self . currentError. condition) ? ( self . isSelected ? notifier. selectedLineColor : notifier. lineColor) : notifier. errorColor)
174
174
}
175
-
175
+
176
176
}
177
177
. frame ( minWidth: 0 , maxWidth: . infinity, minHeight: 0 , maxHeight: . infinity, alignment: . bottomLeading)
178
178
}
@@ -194,7 +194,7 @@ extension FloatingLabelTextField {
194
194
notifier. leftView = AnyView ( view ( ) )
195
195
return self
196
196
}
197
-
197
+
198
198
/// Sets the right view.
199
199
public func rightView< LRView: View > ( @ViewBuilder _ view: @escaping ( ) -> LRView ) -> Self {
200
200
notifier. rightView = AnyView ( view ( ) )
@@ -210,19 +210,19 @@ extension FloatingLabelTextField {
210
210
notifier. textAlignment = alignment
211
211
return self
212
212
}
213
-
213
+
214
214
/// Sets the secure text entry for TextField.
215
215
public func isSecureTextEntry( _ isSecure: Bool ) -> Self {
216
216
notifier. isSecureTextEntry = isSecure
217
217
return self
218
218
}
219
-
219
+
220
220
/// Whether users can interact with this.
221
221
public func disabled( _ isDisabled: Bool ) -> Self {
222
222
notifier. disabled = isDisabled
223
223
return self
224
224
}
225
-
225
+
226
226
/// Whether this view participates in hit test operations.
227
227
public func allowsHitTesting( _ isAllowsHitTesting: Bool ) -> Self {
228
228
notifier. allowsHitTesting = isAllowsHitTesting
@@ -238,19 +238,19 @@ extension FloatingLabelTextField {
238
238
notifier. lineHeight = height
239
239
return self
240
240
}
241
-
241
+
242
242
/// Sets the selected line height.
243
243
public func selectedLineHeight( _ height: CGFloat ) -> Self {
244
244
notifier. selectedLineHeight = height
245
245
return self
246
246
}
247
-
247
+
248
248
/// Sets the line color.
249
249
public func lineColor( _ color: Color ) -> Self {
250
250
notifier. lineColor = color
251
251
return self
252
252
}
253
-
253
+
254
254
/// Sets the selected line color.
255
255
public func selectedLineColor( _ color: Color ) -> Self {
256
256
notifier. selectedLineColor = color
@@ -266,19 +266,19 @@ extension FloatingLabelTextField {
266
266
notifier. titleColor = color
267
267
return self
268
268
}
269
-
269
+
270
270
/// Sets the selected title color.
271
271
public func selectedTitleColor( _ color: Color ) -> Self {
272
272
notifier. selectedTitleColor = color
273
273
return self
274
274
}
275
-
275
+
276
276
/// Sets the title font.
277
277
public func titleFont( _ font: Font ) -> Self {
278
278
notifier. titleFont = font
279
279
return self
280
280
}
281
-
281
+
282
282
/// Sets the space between title and text.
283
283
public func spaceBetweenTitleText( _ space: Double ) -> Self {
284
284
notifier. spaceBetweenTitleText = space
@@ -294,13 +294,13 @@ extension FloatingLabelTextField {
294
294
notifier. textColor = color
295
295
return self
296
296
}
297
-
297
+
298
298
/// Sets the selected text color.
299
299
public func selectedTextColor( _ color: Color ) -> Self {
300
300
notifier. selectedTextColor = color
301
301
return self
302
302
}
303
-
303
+
304
304
/// Sets the text font.
305
305
public func textFont( _ font: Font ) -> Self {
306
306
notifier. font = font
@@ -316,7 +316,7 @@ extension FloatingLabelTextField {
316
316
notifier. placeholderColor = color
317
317
return self
318
318
}
319
-
319
+
320
320
/// Sets the placeholder font.
321
321
public func placeholderFont( _ font: Font ) -> Self {
322
322
notifier. placeholderFont = font
@@ -332,25 +332,25 @@ extension FloatingLabelTextField {
332
332
notifier. isShowError = show
333
333
return self
334
334
}
335
-
335
+
336
336
/// Sets the validation conditions.
337
337
public func addValidations( _ conditions: [ TextFieldValidator ] ) -> Self {
338
338
notifier. arrValidator. append ( contentsOf: conditions)
339
339
return self
340
340
}
341
-
341
+
342
342
/// Sets the validation condition.
343
343
public func addValidation( _ condition: TextFieldValidator ) -> Self {
344
344
notifier. arrValidator. append ( condition)
345
345
return self
346
346
}
347
-
347
+
348
348
/// Sets the error color.
349
349
public func errorColor( _ color: Color ) -> Self {
350
350
notifier. errorColor = color
351
351
return self
352
352
}
353
-
353
+
354
354
/// Sets the field is required or not with message.
355
355
public func isRequiredField( _ required: Bool , with message: String ) -> Self {
356
356
notifier. isRequiredField = required
0 commit comments