Skip to content

Commit 2cd1785

Browse files
committed
BREAKING CHANGE: BottomSheet is now an AbsoluteLayout
This was a necessary change to fix layout issues when the actual `bottomsheet` as dynamic height If you add child inside `BottomSheet` and want the previous behavior / layout, simply wrap your children in a `<GridLayout width=“100%’ height=“100%”/>`
1 parent 407ce02 commit 2cd1785

File tree

1 file changed

+52
-98
lines changed

1 file changed

+52
-98
lines changed

src/ui-persistent-bottomsheet/index.ts

Lines changed: 52 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,22 @@ import {
44
GestureState,
55
GestureStateEventData,
66
GestureTouchEventData,
7-
HandlerType,
8-
Manager,
7+
HandlerType, install as installGestures, Manager,
98
PanGestureHandler,
10-
PanGestureHandlerOptions,
11-
install as installGestures
9+
PanGestureHandlerOptions
1210
} from '@nativescript-community/gesturehandler';
1311
import {
12+
AbsoluteLayout,
1413
Animation,
15-
AnimationDefinition,
16-
CSSType,
17-
Color,
18-
CoreTypes,
19-
EventData,
14+
AnimationDefinition, booleanConverter, Color,
15+
CoreTypes, CSSType, EventData,
2016
GridLayout,
2117
Property,
2218
ScrollEventData,
2319
ScrollView,
2420
TouchGestureEventData,
2521
Utils,
26-
View,
27-
booleanConverter
22+
View
2823
} from '@nativescript/core';
2924
const OPEN_DURATION = 200;
3025
const CLOSE_DURATION = 200;
@@ -58,7 +53,7 @@ export const bottomSheetProperty = new Property<PersistentBottomSheet, View>({
5853
name: 'bottomSheet',
5954
defaultValue: undefined,
6055
valueChanged: (target, oldValue, newValue) => {
61-
(target as any)._onBottomSheetChanged(oldValue, newValue);
56+
target._onBottomSheetChanged(oldValue, newValue);
6257
}
6358
});
6459
export const gestureEnabledProperty = new Property<PersistentBottomSheet, boolean>({
@@ -83,7 +78,7 @@ export const translationFunctionProperty = new Property<PersistentBottomSheet, F
8378
});
8479

8580
@CSSType('PersistentBottomSheet')
86-
export class PersistentBottomSheet extends GridLayout {
81+
export class PersistentBottomSheet extends AbsoluteLayout {
8782
public bottomSheet: View;
8883
public scrollViewId: string;
8984
// isPanning = false;
@@ -98,7 +93,7 @@ export class PersistentBottomSheet extends GridLayout {
9893
private isAnimating = false;
9994
private prevDeltaY = 0;
10095
private viewHeight = 0;
101-
private bottomViewHeight = 0;
96+
// private bottomViewHeight = 0;
10297

10398
private lastScrollY: number;
10499
private lastTouchY: number;
@@ -150,8 +145,7 @@ export class PersistentBottomSheet extends GridLayout {
150145
deltaY -= Utils.layout.toDeviceIndependentPixels(this.getSafeAreaInsets().top);
151146
}
152147
const y = data.y + deltaY;
153-
// console.log('shouldStartGesture ', safeAreatop, data, y, this.viewHeight - (this.translationMaxOffset - this.translationY), this.translationY, this.translationMaxOffset, this.viewHeight);
154-
if (y < this.viewHeight - (this.bottomViewHeight - this.translationY)) {
148+
if (y < this.viewHeight + this.translationY) {
155149
return false;
156150
}
157151
if (this._scrollView) {
@@ -162,27 +156,10 @@ export class PersistentBottomSheet extends GridLayout {
162156
}
163157
return true;
164158
}
165-
// initNativeGestureHandler(newValue: View) {
166-
// // console.log('initNativeGestureHandler', newValue);
167-
// if (!this.nativeGestureHandler) {
168-
// const manager = Manager.getInstance();
169-
// const gestureHandler = manager.createGestureHandler(HandlerType.NATIVE_VIEW, NATIVE_GESTURE_TAG, {
170-
// shouldActivateOnStart: true,
171-
// shouldCancelWhenOutside: false,
172-
// // simultaneousHandlers: [PAN_GESTURE_TAG],
173-
// });
174-
// // gestureHandler.on(GestureHandlerStateEvent, this.onNativeGestureState, this);
175-
// this.nativeGestureHandler = gestureHandler as any;
176-
// }
177-
// if (this.nativeGestureHandler.getView() !== newValue) {
178-
// // this.nativeGestureHandler.attachToView(newValue);
179-
// }
180-
// }
181159
get translationY() {
182160
return this._translationY;
183161
}
184162
set translationY(value: number) {
185-
// console.log('set translationY', value)
186163
if (this._translationY !== -1) {
187164
this.isScrollEnabled = value === 0;
188165
}
@@ -230,10 +207,10 @@ export class PersistentBottomSheet extends GridLayout {
230207
}
231208
}
232209
[stepIndexProperty.setNative](value: number) {
233-
if (this.viewHeight !== 0) {
234-
// we are layed out
235-
this.animateToPosition(this.steps[value]);
236-
}
210+
// if (this.viewHeight !== 0) {
211+
// we are layed out
212+
this.animateToPosition(this.steps[value]);
213+
// }
237214
}
238215
[backdropColorProperty.setNative](value: Color) {
239216
if (!this.backDrop && this.bottomSheet) {
@@ -242,7 +219,6 @@ export class PersistentBottomSheet extends GridLayout {
242219
}
243220
}
244221
protected addBackdropView(index: number) {
245-
// console.log('addBackdropView', index);
246222
this.backDrop = new GridLayout();
247223
this.backDrop.backgroundColor = this.backdropColor;
248224
this.backDrop.opacity = 0;
@@ -287,14 +263,24 @@ export class PersistentBottomSheet extends GridLayout {
287263
}
288264
}
289265

290-
private _onBottomSheetChanged(oldValue: View, newValue: View) {
266+
_onBottomSheetChanged(oldValue: View, newValue: View) {
291267
if (oldValue) {
292268
this.removeChild(oldValue);
293269
}
294270
if (newValue) {
295271
newValue.iosOverflowSafeAreaEnabled = false;
296-
newValue.verticalAlignment = 'bottom';
297-
newValue.on('layoutChanged', this.onBottomLayoutChange, this);
272+
if (!newValue.width) {
273+
newValue.width = {
274+
unit: '%',
275+
value: 100
276+
};
277+
}
278+
// newValue.top = {
279+
// unit: 'px',
280+
// value: this.viewHeight
281+
// };
282+
// newValue.verticalAlignment = 'bottom';
283+
// newValue.on('layoutChanged', this.onBottomLayoutChange, this);
298284
let index;
299285
if (!newValue.parent) {
300286
index = this.getChildrenCount();
@@ -311,19 +297,18 @@ export class PersistentBottomSheet extends GridLayout {
311297
}
312298
}
313299

314-
computeTranslationData(height) {
300+
computeTranslationData(ty) {
315301
const max = this.translationMaxOffset;
316-
const diff = height - max;
317302
let value = this._translationY;
318-
const progress = 1 - (this._translationY - diff) / max;
319-
320-
if (global.isIOS && progress === 0 && !this.iosIgnoreSafeArea) {
303+
const diff = max - ty;
304+
const progress = ty / max;
305+
if (__IOS__ && progress === 0 && !this.iosIgnoreSafeArea) {
321306
// if this is the 0 steop ensure it gets hidden even with safeArea
322307
const safeArea = this.getSafeAreaInsets();
323308
value += Utils.layout.toDeviceIndependentPixels(safeArea.bottom);
324309
}
325310
if (this.translationFunction) {
326-
return this.translationFunction(height, value, progress);
311+
return this.translationFunction(ty, value, progress);
327312
}
328313
return {
329314
bottomSheet: {
@@ -338,27 +323,18 @@ export class PersistentBottomSheet extends GridLayout {
338323
const contentView = event.object as GridLayout;
339324
const height = Math.round(Utils.layout.toDeviceIndependentPixels(contentView.getMeasuredHeight()));
340325
this.viewHeight = height;
341-
if (this.translationY === -1 && this.bottomViewHeight !== 0) {
342-
const height = this.bottomViewHeight;
343-
const steps = this.steps;
344-
const step = steps[this.stepIndex];
345-
const ty = height - step;
346-
this.translationY = ty;
347-
const data = this.computeTranslationData(height);
348-
this.applyTrData(data);
326+
if (this.bottomSheet) {
327+
this.bottomSheet.top = {
328+
unit: 'px',
329+
value: contentView.getMeasuredHeight()
330+
};
349331
}
350-
}
351-
private onBottomLayoutChange(event: EventData) {
352-
const contentView = event.object as GridLayout;
353-
const height = Math.round(Utils.layout.toDeviceIndependentPixels(contentView.getMeasuredHeight()));
354-
this.bottomViewHeight = height;
355-
if (this.translationY === -1 && this.viewHeight !== 0) {
356-
const height = this.bottomViewHeight;
332+
if (this.translationY === -1 && this.bottomSheet) {
357333
const steps = this.steps;
358334
const step = steps[this.stepIndex];
359-
const ty = height - step;
360-
this.translationY = ty;
361-
const data = this.computeTranslationData(height);
335+
const ty = step;
336+
this.translationY = -ty;
337+
const data = this.computeTranslationData(ty);
362338
this.applyTrData(data);
363339
}
364340
}
@@ -389,10 +365,6 @@ export class PersistentBottomSheet extends GridLayout {
389365
}
390366
private onTouch(event: TouchGestureEventData) {
391367
let touchY;
392-
// if (this.animationTimer) {
393-
// clearTimeout(this.animationTimer);
394-
// this.animationTimer = null;
395-
// }
396368
// touch event gives you relative touch which varies with translateY
397369
// so we use touch location in the window
398370
if (global.isAndroid) {
@@ -401,20 +373,14 @@ export class PersistentBottomSheet extends GridLayout {
401373
touchY = (event.ios.touches.anyObject() as UITouch).locationInView(null).y;
402374
}
403375
if (event.action === 'down') {
404-
// this.scrollViewTouched = true;
405-
// this.lastScrollY = this.scrollViewVerticalOffset;
406-
// this.scrollViewAtTop = this.lastScrollY === 0;
407-
// if (this.scrollViewAtTop) {
408-
// this.panGestureHandler.cancel();
409-
// }
410376
} else if (event.action === 'up' || event.action === 'cancel') {
411377
if (this.scrollViewTouched) {
412378
this.scrollViewTouched = false;
413379
if (this.scrollViewAtTop) {
414380
this.scrollViewAtTop = this.scrollView.verticalOffset === 0;
415381
const y = touchY - (this.lastTouchY || touchY);
416382
const totalDelta = this.translationY + y;
417-
this.computeAndAnimateEndGestureAnimation(totalDelta);
383+
this.computeAndAnimateEndGestureAnimation(-totalDelta);
418384
}
419385
}
420386
this.isScrollEnabled = true;
@@ -433,9 +399,8 @@ export class PersistentBottomSheet extends GridLayout {
433399
}
434400
const y = touchY - (this.lastTouchY || touchY);
435401
const trY = this.constrainY(this.translationY + y);
436-
const height = this.bottomViewHeight;
437402
this.translationY = trY;
438-
const trData = this.computeTranslationData(height);
403+
const trData = this.computeTranslationData(-trY);
439404
this.applyTrData(trData);
440405
}
441406
this.lastTouchY = touchY;
@@ -462,30 +427,27 @@ export class PersistentBottomSheet extends GridLayout {
462427
const dragToss = 0.05;
463428
const y = translationY - this.prevDeltaY;
464429
const totalDelta = this.translationY + (y + dragToss * velocityY);
465-
this.computeAndAnimateEndGestureAnimation(totalDelta);
430+
this.computeAndAnimateEndGestureAnimation(-totalDelta);
466431
this.prevDeltaY = 0;
467432
}
468433
}
469434

470435
private computeAndAnimateEndGestureAnimation(totalDelta: number) {
471-
const viewHeight = this.bottomViewHeight;
472436
const steps = this.steps;
473437
let stepIndex = 0;
474-
let destSnapPoint = viewHeight - steps[stepIndex];
438+
let destSnapPoint = steps[stepIndex];
475439
let distance = Math.abs(destSnapPoint - totalDelta);
476440
for (let i = 0; i < steps.length; i++) {
477-
const snapPoint = viewHeight - steps[i];
441+
const snapPoint = steps[i];
478442
const distFromSnap = Math.abs(snapPoint - totalDelta);
479443
if (distFromSnap <= Math.abs(destSnapPoint - totalDelta)) {
480444
destSnapPoint = snapPoint;
481445
stepIndex = i;
482446
distance = distFromSnap;
483447
}
484448
}
485-
// stepIndexProperty.nativeValueChange
486-
// this.stepIndex = stepIndex;
487449
stepIndexProperty.nativeValueChange(this, stepIndex);
488-
this.animateToPosition(viewHeight - destSnapPoint, Math.min(distance * 2, OPEN_DURATION));
450+
this.animateToPosition(destSnapPoint, Math.min(distance * 2, OPEN_DURATION));
489451
}
490452
private onGestureTouch(args: GestureTouchEventData) {
491453
const data = args.data;
@@ -500,8 +462,7 @@ export class PersistentBottomSheet extends GridLayout {
500462
const y = deltaY - this.prevDeltaY;
501463
const trY = this.constrainY(this.translationY + y);
502464
this.translationY = trY;
503-
const height = this.bottomViewHeight;
504-
const trData = this.computeTranslationData(height);
465+
const trData = this.computeTranslationData(-trY);
505466
this.applyTrData(trData);
506467
this.prevDeltaY = deltaY;
507468
}
@@ -519,7 +480,7 @@ export class PersistentBottomSheet extends GridLayout {
519480
}
520481

521482
private constrainY(y) {
522-
return Math.max(Math.min(y, this.bottomViewHeight), this.bottomViewHeight - this.translationMaxOffset);
483+
return Math.max(Math.min(y, 0), -this.translationMaxOffset);
523484
}
524485

525486
animating = false;
@@ -539,10 +500,9 @@ export class PersistentBottomSheet extends GridLayout {
539500
event.setAction(android.view.MotionEvent.ACTION_CANCEL);
540501
this.scrollView.nativeViewProtected.dispatchTouchEvent(event);
541502
}
542-
const height = this.bottomViewHeight;
543-
this.translationY = height - position;
544-
const trData = this.computeTranslationData(height);
545-
503+
// const height = this.bottomViewHeight;
504+
this.translationY = -position;
505+
const trData = this.computeTranslationData(position);
546506
const params = Object.keys(trData)
547507
.map((k) => {
548508
const data = trData[k];
@@ -577,12 +537,6 @@ export class PersistentBottomSheet extends GridLayout {
577537
this.isScrollEnabled = true;
578538
this.animating = false;
579539
this.animation = null;
580-
// if (position !== 0) {
581-
// } else {
582-
// // if (this.backDrop) {
583-
// // this.backDrop.visibility = 'hidden';
584-
// // }
585-
// }
586540
}
587541
}
588542
}

0 commit comments

Comments
 (0)