@knotes/nativescript-keyboard-toolbar
Version:
NativeScript Keyboard Toolbar plugin
132 lines (131 loc) • 6.43 kB
JavaScript
import { Application as application, Screen as screen, } from '@nativescript/core';
import { EditableTextBase } from "@nativescript/core/ui/editable-text-base";
import { AnimationCurve } from "@nativescript/core/ui/enums";
import { Page } from "@nativescript/core/ui/page";
import { Frame } from "@nativescript/core/ui/frame";
import { ToolbarBase } from "./keyboard-toolbar.common";
export class Toolbar extends ToolbarBase {
_loaded() {
this.keyboardNotificationObserver = application.ios.addNotificationObserver(UIKeyboardWillChangeFrameNotification, notification => {
const newKeyboardHeight = notification.userInfo.valueForKey(UIKeyboardFrameEndUserInfoKey).CGRectValue.size.height;
if (newKeyboardHeight === this.lastKeyboardHeight) {
return;
}
const isFirstAnimation = this.lastKeyboardHeight === undefined;
this.lastKeyboardHeight = newKeyboardHeight;
if (!isFirstAnimation && this.hasFocus) {
const parent = this.content.parent;
parent.translateY = this.startPositionY - newKeyboardHeight - (this.lastHeight / screen.mainScreen.scale);
}
});
const onViewForIdFound = forView => {
const parent = this.content.parent;
const isText = forView instanceof EditableTextBase;
const hasIQKeyboardManagerInstalled = typeof (IQKeyboardManager) !== "undefined";
const iqKeyboardManagerOriginalDistance = hasIQKeyboardManagerInstalled ? IQKeyboardManager.sharedManager().keyboardDistanceFromTextField : 0;
if (isText) {
forView.on("focus", () => {
if (hasIQKeyboardManagerInstalled) {
IQKeyboardManager.sharedManager().keyboardDistanceFromTextField = iqKeyboardManagerOriginalDistance + parent.height;
}
this.hasFocus = true;
setTimeout(() => {
const animateToY = this.startPositionY - this.lastKeyboardHeight - (this.showWhenKeyboardHidden === true ? 0 : (this.lastHeight / screen.mainScreen.scale));
this.log("focus, animateToY: " + animateToY);
parent.animate({
translate: { x: 0, y: animateToY },
curve: AnimationCurve.cubicBezier(.32, .49, .56, 1),
duration: 370
}).then(() => {
});
});
});
forView.on("blur", () => {
if (hasIQKeyboardManagerInstalled) {
IQKeyboardManager.sharedManager().keyboardDistanceFromTextField = iqKeyboardManagerOriginalDistance;
}
this.hasFocus = false;
const animateToY = this.showWhenKeyboardHidden === true && this.showAtBottomWhenKeyboardHidden !== true ? 0 : this.startPositionY;
this.log("blur, animateToY: " + animateToY);
parent.animate({
translate: { x: 0, y: animateToY },
curve: AnimationCurve.cubicBezier(.32, .49, .56, 1),
duration: 370
}).then(() => {
});
});
}
else {
forView.on("tap", () => {
const animateToY = this.startPositionY - (this.lastHeight / screen.mainScreen.scale);
this.log("tap, animateToY: " + animateToY);
parent.animate({
translate: { x: 0, y: animateToY },
curve: AnimationCurve.cubicBezier(.32, .49, .56, 1),
duration: 370
}).then(() => {
});
});
}
};
this.getViewForId(10)
.then(view => onViewForIdFound(view))
.catch(() => console.log(`\n⌨ ⌨ ⌨ Please make sure forId="<view id>" resolves to a visible view, or the toolbar won't render correctly! Example: <Toolbar forId="myId" height="44">\n\n`));
}
getViewForId(attemptsLeft) {
return new Promise((resolve, reject) => {
if (attemptsLeft-- > 0) {
setTimeout(() => {
let pg;
if (Frame.topmost()) {
pg = Frame.topmost().currentPage;
}
else {
pg = this.content.parent;
while (pg && !(pg instanceof Page)) {
pg = pg.parent;
}
}
const page = pg;
const found = page && page.modal ? page.modal.getViewById(this.forId) : page && page.getViewById(this.forId);
if (found) {
resolve(found);
}
else {
this.getViewForId(attemptsLeft).then(resolve).catch(reject);
}
}, 200);
}
else {
reject();
}
});
}
_unloaded() {
application.ios.removeNotificationObserver(this.keyboardNotificationObserver, UIKeyboardWillChangeFrameNotification);
}
_layout(left, top, right, bottom) {
const parent = this.content.parent;
const newHeight = parent.getMeasuredHeight();
if (newHeight === this.lastHeight) {
return;
}
const { y } = parent.getLocationOnScreen();
this.startPositionY = screen.mainScreen.heightDIPs - y - ((this.showWhenKeyboardHidden === true ? newHeight : 0) / screen.mainScreen.scale);
this.log("_layout, startPositionY: " + this.startPositionY);
if (this.lastHeight === undefined) {
if (this.showWhenKeyboardHidden === true) {
if (this.showAtBottomWhenKeyboardHidden === true) {
parent.translateY = this.startPositionY;
}
}
else {
parent.translateY = this.startPositionY;
}
}
else if (this.lastHeight !== newHeight) {
parent.translateY = this.startPositionY;
}
this.lastHeight = newHeight;
}
}