Nativescript: StackLayout isUserInteractionEnabled="false" value is not working

Created on 30 Nov 2016  Â·  10Comments  Â·  Source: NativeScript/NativeScript

StackLayout isUserInteractionEnabled="false" value is not working

https://docs.nativescript.org/api-reference/classes/_ui_core_view_.view.html#isuserinteractionenabled
Yes I did verify on stackover flow and other channels

I am trying to disable use interaction when I have a activity indicator. Below code is stack layout example.



Which platform(s) does your issue occur on?
Android [For now I tested this on Android alone]

Please provide the following version numbers that your issue occurs with:

  • CLI: (run tns --version to fetch it) 2.4.0
  • Cross-platform modules: (check the 'version' attribute in the
    node_modules/tns-core-modules/package.json file in your project) 2.4.0
  • Runtime(s): (look for the "tns-android" and "tns-ios" properties in the
    package.json file of your project) 2.4.1 (Android)
  • Plugin(s): (look for the version number in the package.json file of your
    project)

Please tell us how to recreate the issue in as much detail as possible.

I have a button which enables the activity indicator, from my function I am trying to set isUserInteractionEnabled to false(Boolean) and trying to disable the interaction on the screen for certain time. But I still can click different buttons on the screen.

Is there code involved? If so, please share the minimal amount of code needed to recreate the problem.

Some pieces of code.




Component function
test() {
this.isLoading = !this.isLoading;
this.defaultTest = false;
}

bug android medium

Most helpful comment

@MadhuSudhanBhaskar Yes. You can write a simple recursive function to do this like this:
TypeScript:

import { View } from "ui/core/view";
import { LayoutBase } from "ui/layouts/layout-base";

export function setIsUserInteractionEnabledRecursive(view: View, newValue: boolean) {
    view.isUserInteractionEnabled = newValue;
    if (view instanceof LayoutBase) {
        let layoutBase = <LayoutBase>view;
        for(let i = 0, length = layoutBase.getChildrenCount(); i < length; i++){
            let child = layoutBase.getChildAt(i);
            setIsUserInteractionEnabledRecursive(child, newValue);
        }
    }
}

JavaScript:

var layout_base_1 = require("ui/layouts/layout-base");
function setIsUserInteractionEnabledRecursive(view, newValue) {
    view.isUserInteractionEnabled = newValue;
    if (view instanceof layout_base_1.LayoutBase) {
        var layoutBase = view;
        for (var i = 0, length = layoutBase.getChildrenCount(); i < length; i++) {
            var child = layoutBase.getChildAt(i);
            setIsUserInteractionEnabledRecursive(child, newValue);
        }
    }
}
exports.setIsUserInteractionEnabledRecursive = setIsUserInteractionEnabledRecursive;

All 10 comments

Hi @MadhuSudhanBhaskar,
Thank you for reporting this issue.
I confirm, that setting up isUserInteractionEnabled to false to some Layout will not affect the child components on Android. I also tested this case on iOS and It should work as expected and setting this property should also affect the inner components. We will investigate this behavior further and will provide possible solution. In the mean time you could set isUserInteractionEnabled to all component, which you would like to have no user interaction.

Sample code:

<StackLayout class="p-20" isUserInteractionEnabled="false">
    <Label text="Tap the button" class="h1 text-center"></Label>
    <Button isUserInteractionEnabled="false" text="TAP" (tap)="onTap()" class="btn btn-primary btn-active"></Button>
    <Label [text]="message" class="h2 text-center" textWrap="true"></Label>
</StackLayout>

Regards,
@tsonevn

Hi @tsonevn

So in that case, I should set a disable attribute on Scroll View also right?. Just for my confirmation, since I have not yet started on IOS it does not work there also, if I understood you properly.

Regards,
Madhu

Hi @MadhuSudhanBhaskar,
Excuse me if I was not clear enough in my previous comment.

In iOS setting isUserInteractionEnabled to false to the Layout should also affect the children. I was able to reproduce the problem only on Android. If you would like to disable the scroll, you should also set isUserInteractionEnabled="false" to the ScrollView.

Hope this helps.

Yes,

Thank you!!

Hope we fix this :) until then will have it on all components of the page

Regards,
Madhu
On 01-Dec-2016 10:32 AM, "Nikolay Tsonev" notifications@github.com wrote:

Hi @MadhuSudhanBhaskar https://github.com/MadhuSudhanBhaskar,
Excuse me if I was not clear enough in my previous comment.

In iOS setting isUserInteractionEnabled to false to the Layout should
also affect the children. I was able to reproduce the problem only on
Android. If you would like to disable the scroll, you should also set
isUserInteractionEnabled="false" to the ScrollView.

Hope this helps.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/NativeScript/NativeScript/issues/3215#issuecomment-264124138,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABE_T8EuUwNUITiq9gLjf0FHJrXbkJW3ks5rDpRDgaJpZM4LApr8
.

Since this is the standard way iOS and Android behave, I will close this issue.

@hamorphis I dint get you, do we have to externally set isUserInteractionEnabled to false on each component in that case?

@MadhuSudhanBhaskar Yes. You can write a simple recursive function to do this like this:
TypeScript:

import { View } from "ui/core/view";
import { LayoutBase } from "ui/layouts/layout-base";

export function setIsUserInteractionEnabledRecursive(view: View, newValue: boolean) {
    view.isUserInteractionEnabled = newValue;
    if (view instanceof LayoutBase) {
        let layoutBase = <LayoutBase>view;
        for(let i = 0, length = layoutBase.getChildrenCount(); i < length; i++){
            let child = layoutBase.getChildAt(i);
            setIsUserInteractionEnabledRecursive(child, newValue);
        }
    }
}

JavaScript:

var layout_base_1 = require("ui/layouts/layout-base");
function setIsUserInteractionEnabledRecursive(view, newValue) {
    view.isUserInteractionEnabled = newValue;
    if (view instanceof layout_base_1.LayoutBase) {
        var layoutBase = view;
        for (var i = 0, length = layoutBase.getChildrenCount(); i < length; i++) {
            var child = layoutBase.getChildAt(i);
            setIsUserInteractionEnabledRecursive(child, newValue);
        }
    }
}
exports.setIsUserInteractionEnabledRecursive = setIsUserInteractionEnabledRecursive;

This is a nice method, however, it doesn't correctly work when setting interactivity back on.
If I set interactivity to false for view "disable-me", it works, tap doesn't happen, but when I set it back to true, the tap event does not happen;

<GridLayout id="disable-me">
   <Label row="0" col="0" (tap)="test()"
</GridLayout>

Hi @dxshindeo,
Thank you for pointing this behavior.
I reviewed that case and found that the above-given workaround will work only for children from type Button.
When you change again isUserInteractionEnabled to true for the Label, the tap event will not be set again to the component.
For your convenience, I have logged new issue, where this behavior has been described.
For further info, you could keep track on the other issue here.

Hope this helps

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.

Was this page helpful?
0 / 5 - 0 ratings