-
-
Notifications
You must be signed in to change notification settings - Fork 117
/
Copy pathindex.ios.ts
156 lines (137 loc) · 5.91 KB
/
index.ios.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { Application, Screen, View, ViewBase, EditableTextBase, CoreTypes, Page, Frame } from '@nativescript/core';
import { ToolbarBase } from './common';
declare const IQKeyboardManager: any;
export class Toolbar extends ToolbarBase {
private startPositionY: number;
private lastHeight: number;
private lastKeyboardHeight: number;
private keyboardNotificationObserver: any;
protected _loaded(): void {
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 = <View>this.content.parent;
parent.translateY = this.startPositionY - newKeyboardHeight - this.lastHeight / Screen.mainScreen.scale;
}
});
const onViewForIdFound = (forView) => {
const parent = this.content.parent as View;
// experimental support for non-text widgets.. but not sure if this is useful, so not documenting it yet
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;
// wrap in a timeout, to make sure this runs after 'UIKeyboardWillChangeFrameNotification'
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 },
// see http://cubic-bezier.com/#.17,.67,.69,1.04
curve: CoreTypes.AnimationCurve.cubicBezier(0.32, 0.49, 0.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: CoreTypes.AnimationCurve.cubicBezier(0.32, 0.49, 0.56, 1), // perhaps make this one a little different as it's the same as the 'show' animation
duration: 370,
})
.then(() => {});
});
} else {
// it's not a text widget, so just animate the toolbar
forView.on('tap', () => {
const animateToY = this.startPositionY - this.lastHeight / Screen.mainScreen.scale;
this.log('tap, animateToY: ' + animateToY);
parent
.animate({
translate: { x: 0, y: animateToY },
// see http://cubic-bezier.com/#.17,.67,.69,1.04
curve: CoreTypes.AnimationCurve.cubicBezier(0.32, 0.49, 0.56, 1),
duration: 370,
})
.then(() => {});
});
}
};
// TODO this can be reused on Android (but I haven't seen the underlying issue there (yet))
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`));
}
// depending on the framework (looking at you, Angular!) it may take longer to find the view, so here we try to get it asap (instead of a fixed 1sec timeout for instance)
private getViewForId(attemptsLeft: number): Promise<ViewBase> {
return new Promise<ViewBase>((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 = <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();
}
});
}
protected _unloaded(): void {
Application.ios.removeNotificationObserver(this.keyboardNotificationObserver, UIKeyboardWillChangeFrameNotification);
}
protected _layout(left: number, top: number, right: number, bottom: number): void {
const parent = <View>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) {
// this moves the keyboardview to the bottom (just move it offscreen/toggle visibility(?) if the user doesn't want to show it without the keyboard being up)
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;
}
}