Yes..verified issue on iOS version of {N} only.
I've got an AbsoluteLayout and in it I create a Label element. Then I've got another Label element stacked on top of it - it's wider and transparent background.
Label #1 has a tap event. Label #2 doesn't. I would like all taps on #1 to be called. Nothing for #2.
On iOS, looks like #2 is not passing thru the tap events.
iOS only.
tns --version to fetch it) 2.4.2iOS platform 2.4.1
Create an AbsoluteLayout. Create a label in it and register tap event. Create another label over it.
Now tap on label#1 - events not being called.
Hey @erjdriver
To prevent the label which is stacked on top to "steal" the tap you can use isUserInteractionEnabled boolean property and set it to false for your top label. This will not only dismiss all gestures for that label but will allow you to detect the gestures for the label positioned below in the visual stack.
For example:
_page.xml_
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<AbsoluteLayout>
<Label id="lbl1" text="This is Label 1" top="10" left="50" height="50" backgroundColor="green" tap="onTappedLabelOne" />
<Label id="lbl2" text="This is Label 2" top="30" left="100" height="50" backgroundColor="yellow" isUserInteractionEnabled="false" />
</AbsoluteLayout>
</Page>
_page.ts_
import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { Label } from "ui/label";
let page;
export function navigatingTo(args: EventData) {
page = <Page>args.object;
}
export function onTappedLabelOne(args) {
console.log("first label tapped!");
var lbl = <Label>args.object;
lbl.text += "ADD!";
}
Now tapping on label one (even if label two is in front of it) will always trigger.
The full sample project with the same property set from code-behind can be found here.
My apologies - I forgot to mention that.
I tried it and it still didn't work. Though I tried it in code - not xml.
label2.isUserInteractionEnabled = false;
Again this problem is in iOS. It works on Android even w/o the above setting of isUserInteractionEnabled.
Since you took the trouble of testing it - I will go back and test it again.
p.s. i did notice that your coordinates for the 2 labels are not overlapping. What happens if you set label #2 coords to the same as that of #1.
Actually - yes it does work!
Originally, I had entered the correct code but the taps were not registering on label #1 - but this was because of another {N} issue - which I think has been fixed in the upcoming release.
Thanks again.
Interestingly, on Android platform - if you set the isUserInteractionEnabled to false - it doesn't pass thru any events.
@erjdriver have you been able to solve this consistently for both platforms?
On iOS - i've got to set isUserInteractionEnabled to false explicitly.
It works without setting explicitly on the Android.
I'm experiencing this issue right now. Works in Android, doesn't work in iOS.
What I've done is used the AbsoluteLayout to position a StackLayout on top of a GridLayout. The layer on top has a Slider which needs to be interactive and beneath it are labels that are tappable. You can swipe left/right the foreground layer to expose the menu items of the background layer from behind.
So I'm going to look into the isUserInteractionEnabled property of the View to be FALSE once the menu below (in the background layer) is exposed.
Kind of a bummer that I need to do this :/
Obviously, when the background menu is closed by either interaction or swipe, I need to set isUserInteractionEnabled to true otherwise, I suppose, the Slider of the foreground layer won't work anymore
PS originally I used the RadListView for the swiping to show the menus below, but when I enabled swiping, the ability to use the Slider stopped working. And not to confuse you, there are two swiping gestures in this UI. One to set the gauge of something and two to expose the background menu. Works in Android!
Update: Updated my code to turn on/off the isUserInteractionEnabled but it doesn't work for me :/ Does anyone have a solution for this?
My View code:
<StackLayout *ngFor="let feeling of feelings;let i = index" class="feeling-gauge-input-parent">
<!-- Header: Emotion's name and emoticon representing sentimental score -->
<AbsoluteLayout class="feeling-gauge-input">
<!-- Background (menu) -->
<GridLayout class="actions" rows="*" columns="auto, *, auto">
<Label col="0" text="Remove" class="edit add-gutter" (tap)="deleteFeeling(i)"></Label>
<Label col="1"></Label>
<StackLayout col="2" class="edit">
<yf-sentiment-changer [(sentiment)]="feeling.sentiment"></yf-sentiment-changer>
</StackLayout>
</GridLayout>
<!-- Foreground: Feeling Gauge/Sentiment Input -->
<StackLayout class="feeling-gauge-input-container">
<StackLayout orientation="horizontal" #panlayers (pan)="onFeelingHeadPan($event, i)" class="header add-gutter-hack">
<Label [text]="feeling.name | howMuchFeeling"></Label>
<yf-feeling-emoticon [sentiment]="feeling.sentiment" [gauge]="feeling.gauge"></yf-feeling-emoticon>
</StackLayout>
</StackLayout>
</AbsoluteLayout>
<!-- Footer: Scale to adjust the Feeling's gauge that directly effects opacity of above emoticon -->
<Slider
minValue="0" maxValue="100" value="0"
[(ngModel)]="feeling.gauge" [ngModelOptions]="{standalone: true}" class="add-gutter gauge-slider"></Slider>
</StackLayout>
What I was trying to do was on pan end, toggle the property, but even so, that won't be perfect for the UX because then the User won't be able to close the open menu without clicking an item or something :/
Some TS:
// high up at the beginning of the class declaration
@ViewChildren('panlayers') foregrounds:QueryList<StackLayout>;
// somewhere in the pan handle function......
if (isIOS) {
if (destX !== 0) {
// we have opened the menu, let's freeze user interactions with the above layer
console.log('turn off isUserInteractionEnabled on foregrounds');
this.foregrounds.forEach((foreground) => {
foreground.isUserInteractionEnabled = false;
});
} else {
// we closed the menu so let's return the normal functioning tap events to the above layer
console.log('turn on isUserInteractionEnabled on foregrounds');
this.foregrounds.forEach((foreground) => {
foreground.isUserInteractionEnabled = true;
});
}
}
Any tips would be greatly appreciated! Technically, the view in question, isn't visually covering the view from behind when it's exposed ? Even still, if we were to get this to work, it still won't be ideal UX :(
Anyone have luck integrating RadListView with swipe features while using a Slider in the ListView ?
Edit2:
Okay, I figured out the issue with isUserInteractionEnabled not working. First, I changed it to the parent element then I removed the ViewChildren reference in replace for a template 1-way data binding approach:
<!-- Foreground: Feeling Gauge/Sentiment Input -->
<StackLayout class="feeling-gauge-input-container" [isUserInteractionEnabled]="swipeMenuesEnabled">
<StackLayout orientation="horizontal" (pan)="onFeelingHeadPan($event, i)" class="header add-gutter-hack">
<Label [text]="feeling.name | howMuchFeeling"></Label>
<yf-feeling-emoticon [sentiment]="feeling.sentiment" [gauge]="feeling.gauge"></yf-feeling-emoticon>
</StackLayout>
</StackLayout>
See [isUserInteractionEnabled]="swipeMenuesEnabled" then in the pan function handler, I toggle the value. It's a step in the right direction, but now I can't close the background menues :/ haha
Open to suggestions!
Edit3: Found a way!
So in addition to Edit2.... I added the following code to the containing AbsoluteLayout:
(tap)="tapAbsoluteLayout()"
Then the function itself:
public tapAbsoluteLayout() {
console.log('hi');
if (! this.swipeMenuesEnabled) {
console.log('enable me');
this.swipeMenuesEnabled = true;
} else {
console.log('no change');
}
}
So if the menu is open, and swiping is disabled, we can enable it on tap which lets the gesture effect the foreground to swipe close to hide the background menues :)
Thank you @NickIliev for pointing out the isUserInteractionEnabled property!
Edit4: Making the new tap event for the AbsoluteLayout a pan event made it better. But still, the User has to tap/pan the area to enable interaction with the child element to swipe the menu closed. Once I figure a way around this, I'll post back. Currently, looking at using the position of the began pan gesture to see if it's not in the menu, then try to call the pan handling function immediately from there... we'll see!
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Hey @erjdriver
To prevent the label which is stacked on top to "steal" the tap you can use isUserInteractionEnabled boolean property and set it to false for your top label. This will not only dismiss all gestures for that label but will allow you to detect the gestures for the label positioned below in the visual stack.
For example:
_page.xml_
_page.ts_
Now tapping on label one (even if label two is in front of it) will always trigger.
The full sample project with the same property set from code-behind can be found here.