1
- import { KeyboardType , TextFieldBase } from './textfield.common' ;
2
- import { backgroundInternalProperty , placeholderColorProperty , keyboardTypeProperty } from '@nativescript/core/ui/editable-text-base' ;
1
+ import { TextFieldBase } from './textfield.common' ;
2
+ import { backgroundInternalProperty , placeholderColorProperty , keyboardTypeProperty , textProperty } from '@nativescript/core/ui/editable-text-base' ;
3
3
import {
4
4
buttonColorProperty ,
5
+ digitsProperty ,
5
6
errorColorProperty ,
6
7
errorProperty ,
7
8
floatingColorProperty ,
@@ -10,14 +11,17 @@ import {
10
11
helperProperty ,
11
12
maxLengthProperty ,
12
13
strokeColorProperty ,
13
- strokeInactiveColorProperty
14
+ strokeInactiveColorProperty ,
14
15
} from 'nativescript-material-core/textbase/cssproperties' ;
15
16
import { themer } from 'nativescript-material-core/core' ;
16
17
import { Color } from '@nativescript/core/color' ;
17
18
import { Style } from '@nativescript/core/ui/styling/style' ;
18
19
import { Background } from '@nativescript/core/ui/styling/background' ;
19
20
import { screen } from '@nativescript/core/platform/platform' ;
20
21
22
+ // it is exported but not in the typings
23
+ const _updateCharactersInRangeReplacementString = require ( '@nativescript/core/ui/editable-text-base' ) . _updateCharactersInRangeReplacementString ;
24
+
21
25
let colorScheme : MDCSemanticColorScheme ;
22
26
function getColorScheme ( ) {
23
27
if ( ! colorScheme ) {
@@ -104,12 +108,120 @@ class TextInputControllerFilledImpl extends MDCTextInputControllerFilled {
104
108
}
105
109
}
106
110
111
+ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
112
+ public static ObjCProtocols = [ UITextFieldDelegate ] ;
113
+
114
+ private _owner : WeakRef < TextField > ;
115
+ private firstEdit : boolean ;
116
+
117
+ public static initWithOwner ( owner : WeakRef < TextField > ) : UITextFieldDelegateImpl {
118
+ const delegate = < UITextFieldDelegateImpl > UITextFieldDelegateImpl . new ( ) ;
119
+ delegate . _owner = owner ;
120
+
121
+ return delegate ;
122
+ }
123
+
124
+ public textFieldShouldBeginEditing ( textField : UITextField ) : boolean {
125
+ this . firstEdit = true ;
126
+ const owner = this . _owner . get ( ) ;
127
+ if ( owner ) {
128
+ return owner . editable ;
129
+ }
130
+
131
+ return true ;
132
+ }
133
+
134
+ public textFieldDidBeginEditing ( textField : UITextField ) : void {
135
+ const owner = this . _owner . get ( ) ;
136
+ if ( owner ) {
137
+ owner . notify ( { eventName : TextField . focusEvent , object : owner } ) ;
138
+ }
139
+ }
140
+
141
+ public textFieldDidEndEditing ( textField : UITextField ) {
142
+ const owner = this . _owner . get ( ) ;
143
+ if ( owner ) {
144
+ if ( owner . updateTextTrigger === 'focusLost' ) {
145
+ textProperty . nativeValueChange ( owner , textField . text ) ;
146
+ }
147
+
148
+ owner . dismissSoftInput ( ) ;
149
+ }
150
+ }
151
+
152
+ public textFieldShouldClear ( textField : UITextField ) {
153
+ this . firstEdit = false ;
154
+ const owner = this . _owner . get ( ) ;
155
+ if ( owner ) {
156
+ textProperty . nativeValueChange ( owner , '' ) ;
157
+ }
158
+
159
+ return true ;
160
+ }
161
+
162
+ public textFieldShouldReturn ( textField : UITextField ) : boolean {
163
+ // Called when the user presses the return button.
164
+ const owner = this . _owner . get ( ) ;
165
+ if ( owner ) {
166
+ if ( owner . closeOnReturn ) {
167
+ owner . dismissSoftInput ( ) ;
168
+ }
169
+ owner . notify ( { eventName : TextField . returnPressEvent , object : owner } ) ;
170
+ }
171
+
172
+ return true ;
173
+ }
174
+
175
+ public textFieldShouldChangeCharactersInRangeReplacementString ( textField : UITextField , range : NSRange , replacementString : string ) : boolean {
176
+ const owner = this . _owner . get ( ) ;
177
+ if ( owner ) {
178
+ // ignore if not in our alllowed digits
179
+ if ( owner . nsdigits && replacementString . length > 0 && NSString . stringWithString ( replacementString ) . rangeOfCharacterFromSet ( owner . nsdigits ) . location === NSNotFound ) {
180
+ return false ;
181
+ }
182
+ if ( owner . secureWithoutAutofill && ! textField . secureTextEntry ) {
183
+ /**
184
+ * Helps avoid iOS 12+ autofill strong password suggestion prompt
185
+ * Discussed in several circles but for example:
186
+ * https://github.com/expo/expo/issues/2571#issuecomment-473347380
187
+ */
188
+ textField . secureTextEntry = true ;
189
+ }
190
+ const delta = replacementString . length - range . length ;
191
+ if ( delta > 0 ) {
192
+ if ( textField . text . length + delta > owner . maxLength ) {
193
+ return false ;
194
+ }
195
+ }
196
+
197
+ if ( owner . updateTextTrigger === 'textChanged' ) {
198
+ if ( textField . secureTextEntry && this . firstEdit ) {
199
+ textProperty . nativeValueChange ( owner , replacementString ) ;
200
+ } else {
201
+ if ( range . location <= textField . text . length ) {
202
+ const newText = NSString . stringWithString ( textField . text ) . stringByReplacingCharactersInRangeWithString ( range , replacementString ) ;
203
+ textProperty . nativeValueChange ( owner , newText ) ;
204
+ }
205
+ }
206
+ }
207
+
208
+ if ( owner . formattedText ) {
209
+ _updateCharactersInRangeReplacementString ( owner . formattedText , range . location , range . length , replacementString ) ;
210
+ }
211
+ }
212
+
213
+ this . firstEdit = false ;
214
+
215
+ return true ;
216
+ }
217
+ }
218
+
107
219
export class TextField extends TextFieldBase {
108
220
nativeViewProtected : MDCTextField ;
109
221
nativeTextViewProtected : MDCTextField ;
110
222
private _controller : MDCTextInputControllerBase ;
111
223
public readonly style : Style & { variant : 'outline' | 'underline' | 'filled' } ;
112
-
224
+ public nsdigits ?: NSCharacterSet ;
113
225
public clearFocus ( ) {
114
226
this . dismissSoftInput ( ) ;
115
227
}
@@ -162,6 +274,13 @@ export class TextField extends TextFieldBase {
162
274
}
163
275
return view ;
164
276
}
277
+ private _delegate : UITextFieldDelegateImpl ;
278
+
279
+ initNativeView ( ) {
280
+ super . initNativeView ( ) ;
281
+ // it will get picked in onLoaded
282
+ this . _delegate = UITextFieldDelegateImpl . initWithOwner ( new WeakRef ( this ) ) ;
283
+ }
165
284
166
285
// TODO: check why i was checking for isFirstResponder
167
286
// with it the blur event is not fired anymore
@@ -179,7 +298,7 @@ export class TextField extends TextFieldBase {
179
298
this . dismissSoftInput ( ) ;
180
299
}
181
300
182
- public setSelection ( start :number , stop ?:number ) {
301
+ public setSelection ( start : number , stop ?: number ) {
183
302
const view = this . nativeTextViewProtected ;
184
303
if ( stop !== undefined ) {
185
304
const begin = view . beginningOfDocument ;
@@ -238,6 +357,13 @@ export class TextField extends TextFieldBase {
238
357
[ errorProperty . setNative ] ( value : string ) {
239
358
this . _controller . setErrorTextErrorAccessibilityValue ( value , value ) ;
240
359
}
360
+ [ digitsProperty . setNative ] ( value : string ) {
361
+ if ( value && value . length > 0 ) {
362
+ this . nsdigits = NSCharacterSet . characterSetWithCharactersInString ( value ) ;
363
+ } else {
364
+ this . nsdigits = null ;
365
+ }
366
+ }
241
367
[ backgroundInternalProperty . setNative ] ( value : Background ) {
242
368
switch ( this . variant ) {
243
369
case 'none' :
@@ -256,48 +382,4 @@ export class TextField extends TextFieldBase {
256
382
}
257
383
}
258
384
}
259
-
260
-
261
- [ keyboardTypeProperty . setNative ] ( value :KeyboardType ) {
262
- let newKeyboardType : UIKeyboardType ;
263
- switch ( value ) {
264
- case "datetime" :
265
- newKeyboardType = UIKeyboardType . NumbersAndPunctuation ;
266
- break ;
267
-
268
- case "phone" :
269
- newKeyboardType = UIKeyboardType . PhonePad ;
270
- break ;
271
-
272
- case "number" :
273
- case "numberDecimal" :
274
- case "numberSigned" :
275
- newKeyboardType = UIKeyboardType . NumbersAndPunctuation ;
276
- break ;
277
-
278
- case "url" :
279
- newKeyboardType = UIKeyboardType . URL ;
280
- break
281
- ;
282
- case "email" :
283
- newKeyboardType = UIKeyboardType . EmailAddress ;
284
- break ;
285
-
286
- case "integer" :
287
- case "numberPassword" :
288
- newKeyboardType = UIKeyboardType . NumberPad ;
289
- break ;
290
-
291
- default :
292
- let kt = + value ;
293
- if ( ! isNaN ( kt ) ) {
294
- newKeyboardType = < UIKeyboardType > kt ;
295
- } else {
296
- newKeyboardType = UIKeyboardType . Default ;
297
- }
298
- break ;
299
- }
300
-
301
- this . nativeTextViewProtected . keyboardType = newKeyboardType ;
302
- }
303
385
}
0 commit comments