ios only: starting a transition animation when another transition is pending causes current page to be deleted, seems to be related to a CSS bug.
cjohn001 opened this issue · 1 comments
Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):
tns info
✔ Getting NativeScript components versions information...
✔ Component nativescript has 8.4.0 version and is up to date.
✔ Component @nativescript/core has 8.4.3 version and is up to date.
✔ Component @nativescript/ios has 8.4.0 version and is up to date.
✔ Component @nativescript/android has 8.4.0 version and is up to date.
"@angular/animations": "15.0.4",
"@angular/common": "15.0.4",
"@angular/compiler": "15.0.4",
"@angular/core": "15.0.4",
"@angular/forms": "15.0.4",
"@angular/platform-browser": "15.0.4",
"@angular/platform-browser-dynamic": "15.0.4",
"@angular/router": "15.0.4",
"@nativescript/angular": "15.0.1",
"@nativescript/core": "8.4.3",
Describe the bug
When a transition animation is triggered during another transition animation is pending, this leads to the current page to be deleted, see example video. I suspect it to be related somehow with Animation cancel events as I am seeing the issue arising when canceled animations are present (Trace.categories.Animation)
To Reproduce
You can create a button which starts a navigation transition. If you quickly press the button 2 times, the second navigation requests deletes the current page. Seems like canceling of the pending transition brakes the ui
this.router.navigate( ['someRoute'], { transition: { name: 'slideLeft' }, clearHistory: false } );
I am seeing the issue in different places. For example on a button tap I call a dismissSoftInput followed by a router.navigate call, which, when quickly double taped, breaks the ui.
In a different place I am using a Label as a button which when tapped calls a router.navigate. Quick double tap again breaks ui. There I have the following directive attached to the label. Double tap cancels the animation and I assume therefore breaks the ui
@Directive({
selector: '[buttonTouchAnimation]'
})
export class ButtonTouchAnimationDirective {
private _element: ElementRef;
private _currentAnimation: Animation;
private _baseBackgroundColor: Color;
//////////////////////////////////////////////////////////////////////////////////////////////////
constructor(el: ElementRef) {
this._element = el;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
@HostListener('touch', ['$event'])
onTouch(args: TouchGestureEventData): void {
const view = this._element.nativeElement as View;
if (view.isEnabled) {
if (args.action === 'down') {
this._baseBackgroundColor = view.backgroundColor as Color;
view._goToVisualState('highlighted');
this.animatePressed();
} else if (args.action === 'up' || args.action === 'cancel') {
view._goToVisualState('normal');
this.animateReleased();
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
private async animatePressed(): Promise<void> {
if (this._currentAnimation?.isPlaying) {
this._currentAnimation.cancel();
}
this._currentAnimation = (this._element.nativeElement as View).createAnimation({
backgroundColor: new Color(255, 64, 81, 97),
curve: CoreTypes.AnimationCurve.easeIn,
duration: TAP_ACTION_INTERVAL
});
this._currentAnimation.play().catch((e: any) => {});
}
//////////////////////////////////////////////////////////////////////////////////////////////////
private async animateReleased(): Promise<void> {
if (!this._currentAnimation?.isPlaying) {
this._currentAnimation.cancel();
}
this._currentAnimation = this._element.nativeElement
.animate({
backgroundColor: this._baseBackgroundColor,
curve: CoreTypes.AnimationCurve.easeIn,
duration: TAP_ACTION_INTERVAL
})
.catch((e: any) => {});
}
}
Expected behavior
the transition does not break even if called twice. Second transition should be canceled instead of interrupting the ongoing transition
Example.mov
Hello together,
I was able to find a workaround for the problem which may help to analyse the source of the issue. Interestingly when I provide margin-left as inline style (style="margin-left: 5;") than the transition animation works as expected. Seems like cancelation of the animation somehow breaks something CSS related.
<Label buttonTouchAnimation class="fsap icon-button" style="margin-left: 5;" text="" (tap)="onTap()" horizontalAlignment="left" verticalAlignment="center"></Label>