diff --git a/src/components/content/content.ts b/src/components/content/content.ts index 500c570e1e1..d159f931de8 100644 --- a/src/components/content/content.ts +++ b/src/components/content/content.ts @@ -639,6 +639,10 @@ export class Content extends Ion implements OnDestroy, AfterViewInit, IContent { */ addScrollPadding(newPadding: number) { assert(typeof this._scrollPadding === 'number', '_scrollPadding must be a number'); + if (newPadding === 0) { + this._inputPolling = false; + this._scrollPadding = -1; + } if (newPadding > this._scrollPadding) { console.debug(`content, addScrollPadding, newPadding: ${newPadding}, this._scrollPadding: ${this._scrollPadding}`); @@ -663,13 +667,13 @@ export class Content extends Ion implements OnDestroy, AfterViewInit, IContent { this._keyboard.onClose(() => { console.debug(`content, clearScrollPaddingFocusOut _keyboard.onClose`); - this._inputPolling = false; - this._scrollPadding = -1; this.addScrollPadding(0); }, 200, 3000); } } + + /** * Tell the content to recalculate its dimensions. This should be called * after dynamically adding/removing headers, footers, or tabs. diff --git a/src/components/input/input.ts b/src/components/input/input.ts index 30ea65663f1..47440738e3e 100644 --- a/src/components/input/input.ts +++ b/src/components/input/input.ts @@ -284,19 +284,24 @@ export class TextInput extends BaseInput implements IonicFormInput { return; } - const blurOnScroll = config.getBoolean('hideCaretOnScroll', false); - if (blurOnScroll) { + const hideCaretOnScroll = config.getBoolean('hideCaretOnScroll', false); + if (hideCaretOnScroll) { this._enableHideCaretOnScroll(); } - - const resizeAssist = config.getBoolean('resizeAssist', false); - if (resizeAssist) { - this._keyboardHeight = 60; - this._enableResizeAssist(); + const win = _plt.win() as any; + const keyboardPlugin = win.Ionic && win.Ionic.keyboardPlugin; + if (keyboardPlugin) { + const keyboardResizes = config.getBoolean('keyboardResizes', false); + if (keyboardResizes) { + this._keyboardHeight = config.getNumber('keyboardSafeArea', 60); + this._enableScrollMove(); + } else { + this._enableScrollPadding(); + this._enableScrollMove(); + } } else { this._useAssist = config.getBoolean('scrollAssist', false); - const usePadding = config.getBoolean('scrollPadding', this._useAssist); if (usePadding) { this._enableScrollPadding(); @@ -528,9 +533,8 @@ export class TextInput extends BaseInput implements IonicFormInput { this.ionFocus.subscribe(() => { const content = this._content; - - // add padding to the bottom of the scroll view (if needed) - content.addScrollPadding(this._getScrollData().scrollPadding); + const scrollPadding = this._getScrollData().scrollPadding; + content.addScrollPadding(scrollPadding); content.clearScrollPaddingFocusOut(); }); } @@ -560,13 +564,13 @@ export class TextInput extends BaseInput implements IonicFormInput { } } - _enableResizeAssist() { + _enableScrollMove() { assert(this._content, 'content is undefined'); console.debug('Input: enableAutoScroll'); this.ionFocus.subscribe(() => { const scrollData = this._getScrollData(); - if (Math.abs(scrollData.scrollAmount) > 100) { + if (Math.abs(scrollData.scrollAmount) > 4) { this._content.scrollTo(0, scrollData.scrollTo, scrollData.scrollDuration); } }); @@ -722,7 +726,8 @@ export function getScrollData( inputOffsetHeight: number, scrollViewDimensions: ContentDimensions, keyboardHeight: number, - plaformHeight: number): ScrollData { + plaformHeight: number +): ScrollData { // compute input's Y values relative to the body const inputTop = (inputOffsetTop + scrollViewDimensions.contentTop - scrollViewDimensions.scrollTop); const inputBottom = (inputTop + inputOffsetHeight); @@ -753,6 +758,15 @@ export function getScrollData( const scrollData: ScrollData = newScrollData(); + // when auto-scrolling, there also needs to be enough + // content padding at the bottom of the scroll view + // always add scroll padding when a text input has focus + // this allows for the content to scroll above of the keyboard + // content behind the keyboard would be blank + // some cases may not need it, but when jumping around it's best + // to have the padding already rendered so there's no jank + scrollData.scrollPadding = keyboardHeight; + if (inputTopWithinSafeArea && inputBottomWithinSafeArea) { // Input top within safe area, bottom within safe area // no need to scroll to a position, it's good as-is @@ -788,15 +802,6 @@ export function getScrollData( // figure out where it should scroll to for the best position to the input scrollData.scrollTo = (scrollViewDimensions.scrollTop - scrollData.scrollAmount); - // when auto-scrolling, there also needs to be enough - // content padding at the bottom of the scroll view - // always add scroll padding when a text input has focus - // this allows for the content to scroll above of the keyboard - // content behind the keyboard would be blank - // some cases may not need it, but when jumping around it's best - // to have the padding already rendered so there's no jank - scrollData.scrollPadding = keyboardHeight; - // calculate animation duration const distance = Math.abs(scrollData.scrollAmount); const duration = distance / SCROLL_ASSIST_SPEED; diff --git a/src/components/input/test/highlight/pages/root-page/root-page.html b/src/components/input/test/highlight/pages/root-page/root-page.html index 9529c9bdcda..9f788614479 100644 --- a/src/components/input/test/highlight/pages/root-page/root-page.html +++ b/src/components/input/test/highlight/pages/root-page/root-page.html @@ -112,6 +112,7 @@ border: 1px solid gray; border-radius: 5px; width: auto; +height: 6vh; transform: translateZ(0);" placeholder="chat here"> \ No newline at end of file diff --git a/src/platform/keyboard.ts b/src/platform/keyboard.ts index b6f24c519f3..6cc5a5e7eb6 100644 --- a/src/platform/keyboard.ts +++ b/src/platform/keyboard.ts @@ -27,9 +27,9 @@ export class Keyboard { _tmr: number; - willShow = new EventEmitter(); + willShow = new EventEmitter(); willHide = new EventEmitter(); - didShow = new EventEmitter(); + didShow = new EventEmitter(); didHide = new EventEmitter(); eventsAvailable = false; @@ -43,7 +43,7 @@ export class Keyboard { this.focusOutline(config.get('focusOutline')); const win = _plt.win(); - if (config.getBoolean('keyboardResizes', false)) { + if (win.Ionic && win.Ionic.keyboardPlugin) { this.listenV2(win); } else { this.listenV1(win); @@ -52,9 +52,9 @@ export class Keyboard { private listenV2(win: any) { const platform = this._plt; - platform.registerListener(win, 'keyboardWillShow', () => { + platform.registerListener(win, 'keyboardWillShow', (ev: any) => { this._zone.run(() => { - this.willShow.emit(); + this.willShow.emit(ev.keyboardHeight); }); }, { zone: false, passive: true }); @@ -64,9 +64,9 @@ export class Keyboard { }); }, { zone: false, passive: true }); - platform.registerListener(win, 'keyboardDidShow', () => { + platform.registerListener(win, 'keyboardDidShow', (ev: any) => { this._zone.run(() => { - this.didShow.emit(); + this.didShow.emit(ev.keyboardHeight); }); }, { zone: false, passive: true }); @@ -268,6 +268,18 @@ export class Keyboard { return false; } + /** + * Set to true to hide the additional toolbar that is on top of the keyboard. + * This toolbar features the Prev, Next, and Done buttons. + * @param hidden + */ + hideFormAccessoryBar(hidden: boolean) { + const win = this._plt.win() as any; + if (win && win.Keyboard && win.Keyboard.hideFormAccessoryBar) { + win.Keyboard.hideFormAccessoryBar(hidden); + } + } + } diff --git a/src/platform/platform-registry.ts b/src/platform/platform-registry.ts index bfee91daf22..d3bb5b0b8b6 100644 --- a/src/platform/platform-registry.ts +++ b/src/platform/platform-registry.ts @@ -109,16 +109,15 @@ export const PLATFORM_CONFIGS: { [key: string]: PlatformConfig } = { hoverCSS: false, inputBlurring: isIos, inputCloning: isIos, - keyboardHeight: 300, + keyboardHeight: 250, mode: 'ios', - scrollAssist: isIos, statusbarPadding: isCordova, swipeBackEnabled: isIos, tapPolyfill: isIosUIWebView, virtualScrollEventAssist: isIosUIWebView, disableScrollAssist: isIos, + scrollAssist: isIos, keyboardResizes: keyboardResizes, - resizeAssist: keyboardResizes, }, isMatch(plt: Platform) { return plt.isPlatformMatch('ios', ['iphone', 'ipad', 'ipod'], ['windows phone']);