@@ -205,18 +205,18 @@ class TextEditingElement {
205
205
206
206
/// Timer that times when to set the location of the input text.
207
207
///
208
- /// This is only used for IOS . In IOS , virtual keyboard shifts the screen.
208
+ /// This is only used for iOS . In iOS , virtual keyboard shifts the screen.
209
209
/// There is no callback to know if the keyboard is up and how much the screen
210
210
/// has shifted. Therefore instead of listening to the shift and passing this
211
211
/// information to Flutter Framework, we are trying to stop the shift.
212
212
///
213
- /// In IOS , the virtual keyboard shifts the screen up if the focused input
213
+ /// In iOS , the virtual keyboard shifts the screen up if the focused input
214
214
/// element is under the keyboard or very close to the keyboard. Before the
215
215
/// focus is called we are positioning it offscreen. The location of the input
216
- /// in IOS is set to correct place, 100ms after focus. We use this timer for
216
+ /// in iOS is set to correct place, 100ms after focus. We use this timer for
217
217
/// timing this delay.
218
218
Timer _positionInputElementTimer;
219
- static const Duration _delayBeforePositining =
219
+ static const Duration _delayBeforePositioning =
220
220
const Duration (milliseconds: 100 );
221
221
222
222
final HybridTextEditing owner;
@@ -247,7 +247,7 @@ class TextEditingElement {
247
247
void configureInputElementForIOS () {
248
248
if (browserEngine != BrowserEngine .webkit ||
249
249
operatingSystem != OperatingSystem .iOs) {
250
- // Only relevant on Safari Mobile and Chrome on IOS .
250
+ // Only relevant on Safari-based on iOS .
251
251
return ;
252
252
}
253
253
@@ -293,30 +293,8 @@ class TextEditingElement {
293
293
}
294
294
295
295
if (owner.doesKeyboardShiftInput) {
296
- /// Position the element outside of the page before focusing on it.
297
- ///
298
- /// See [_positionInputElementTimer] .
299
- owner.setStyleOutsideOfScreen (domElement);
300
-
301
- _subscriptions.add (domElement.onFocus.listen ((_) {
302
- // Cancel previous timer if exists.
303
- _positionInputElementTimer? .cancel ();
304
- _positionInputElementTimer = Timer (_delayBeforePositining, () {
305
- if (textEditing.inputElementNeedsToBePositioned) {
306
- configureInputElementForIOS ();
307
- }
308
- });
309
-
310
- /// When the virtual keyboard is closed on IOS, onBlur is triggered.
311
- _subscriptions.add (domElement.onBlur.listen ((_) {
312
- /// Cancel the timer since there is no need to set the location of the
313
- /// input element anymore. It needs to be focused again to be editable
314
- /// by the user.
315
- _positionInputElementTimer? .cancel ();
316
- }));
317
- }));
296
+ _preventShiftDuringFocus ();
318
297
}
319
-
320
298
domElement.focus ();
321
299
322
300
if (_lastEditingState != null ) {
@@ -343,6 +321,7 @@ class TextEditingElement {
343
321
}
344
322
_subscriptions.clear ();
345
323
_positionInputElementTimer? .cancel ();
324
+ _positionInputElementTimer = null ;
346
325
owner.inputPositioned = false ;
347
326
_removeDomElement ();
348
327
}
@@ -373,6 +352,32 @@ class TextEditingElement {
373
352
domElement.focus ();
374
353
}
375
354
355
+ void _preventShiftDuringFocus () {
356
+ // Position the element outside of the page before focusing on it.
357
+ //
358
+ // See [_positionInputElementTimer].
359
+ owner.setStyleOutsideOfScreen (domElement);
360
+
361
+ _subscriptions.add (domElement.onFocus.listen ((_) {
362
+ // Cancel previous timer if exists.
363
+ _positionInputElementTimer? .cancel ();
364
+ _positionInputElementTimer = Timer (_delayBeforePositioning, () {
365
+ if (textEditing.inputElementNeedsToBePositioned) {
366
+ configureInputElementForIOS ();
367
+ }
368
+ });
369
+
370
+ // When the virtual keyboard is closed on iOS, onBlur is triggered.
371
+ _subscriptions.add (domElement.onBlur.listen ((_) {
372
+ // Cancel the timer since there is no need to set the location of the
373
+ // input element anymore. It needs to be focused again to be editable
374
+ // by the user.
375
+ _positionInputElementTimer? .cancel ();
376
+ _positionInputElementTimer = null ;
377
+ }));
378
+ }));
379
+ }
380
+
376
381
void setEditingState (EditingState editingState) {
377
382
_lastEditingState = editingState;
378
383
if (! _enabled || ! editingState.isValid) {
@@ -406,6 +411,14 @@ class TextEditingElement {
406
411
..addRange (_createRange (editingState));
407
412
break ;
408
413
}
414
+
415
+
416
+ if (owner.inputElementNeedsToBePositioned) {
417
+ _preventShiftDuringFocus ();
418
+ }
419
+
420
+ // Re-focuses when setting editing state.
421
+ domElement.focus ();
409
422
}
410
423
411
424
/// Swap out the current DOM element and replace it with a new one of type
@@ -624,9 +637,9 @@ class HybridTextEditing {
624
637
/// Also used to define if a keyboard is needed.
625
638
bool _isEditing = false ;
626
639
627
- /// Flag indicating the input element needs to be positioned.
640
+ /// Indicates whether the input element needs to be positioned.
628
641
///
629
- /// See [TextEditingElement._delayBeforePositining ] .
642
+ /// See [TextEditingElement._delayBeforePositioning ] .
630
643
bool get inputElementNeedsToBePositioned =>
631
644
! inputPositioned &&
632
645
_isEditing &&
@@ -765,14 +778,14 @@ class HybridTextEditing {
765
778
/// to be shifted by a virtual keyboard or if the input is already positioned.
766
779
///
767
780
/// Otherwise positioning will be done after focusing on the input.
768
- /// See [TextEditingElement._delayBeforePositining ] .
781
+ /// See [TextEditingElement._delayBeforePositioning ] .
769
782
bool get _canPositionInput => inputPositioned || ! doesKeyboardShiftInput;
770
783
771
- /// Flag indicating if virtual keyboard shifts the location of input element.
784
+ /// Indicates whether virtual keyboard shifts the location of input element.
772
785
///
773
786
/// Value decided using the operating system and the browser engine.
774
787
///
775
- /// In IOS , the virtual keyboard might shifts the screen up to make input
788
+ /// In iOS , the virtual keyboard might shifts the screen up to make input
776
789
/// visible depending on the location of the focused input element.
777
790
bool get doesKeyboardShiftInput =>
778
791
browserEngine == BrowserEngine .webkit &&
@@ -807,15 +820,15 @@ class HybridTextEditing {
807
820
..transform = transformCss;
808
821
}
809
822
810
- // TODO(flutter_web): When the browser closes and re-opens the virtual
811
- // shifts the page in IOS . Call this method from visibility change listener
823
+ // TODO(flutter_web): After the browser closes and re-opens the virtual
824
+ // shifts the page in iOS . Call this method from visibility change listener
812
825
// attached to body.
813
- /// Set the dom elements location somewhere outside of the screen.
826
+ /// Set the dom element's location somewhere outside of the screen.
814
827
///
815
- /// This is useful for not triggering a scroll when IOS virtual keyboard is
828
+ /// This is useful for not triggering a scroll when iOS virtual keyboard is
816
829
/// coming up.
817
830
///
818
- /// See [TextEditingElement._delayBeforePositining ] .
831
+ /// See [TextEditingElement._delayBeforePositioning ] .
819
832
void setStyleOutsideOfScreen (html.HtmlElement domElement) {
820
833
domElement.style.transform = 'translate(-9999px, -9999px)' ;
821
834
}
0 commit comments