Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] iOS RELEASE only: f9p Button + CommunityToolkit.AsyncCommand or a Clicked event mysteriously stops firing #112

Open
smalgin opened this issue Jan 11, 2023 · 1 comment

Comments

@smalgin
Copy link
Contributor

smalgin commented Jan 11, 2023

Description

The button in question is a Back button that drives the Position property of a CollectionView.
It should be always enabled, except when it's a first page of a collection view. (Position ==0)
The XAML and code below actually works in all the simulators and also on Android Release build.

However, on iOS Release build the following happens:
When you jump between pages like this: 1-2-1-2-1-2 - at some point the Command event handler stops firing.
In fact, even Clicked event handler stops firing, as I found by looking at the app's debug telemetry stream.
The button stays Enabled, but tapping doesn't produce any events.

NOTE: When the same Page is created and used in another place in the app - it works. A mystery!

WORKAROUND: Replace f2p:Button with a regular Xamarin Button.

Feel free to close, I just want to track a workaround for people's convenience.
There's some work to have a regular Button look as fancy as f9p:Button, but at least I don't have to debug my app by a telemetry log stream.

XAML:

<Button x:Name="prevButton" Grid.Column="0" BackgroundColor="{StaticResource GeneralButtonBackground}" TextColor="{StaticResource GeneralButtonText}" CornerRadius="1" Text="Back" FontSize="Medium" Command="{Binding PreviousPageCommand}" CommandParameter="{Binding BackEnabled, Mode=OneWay}" >

Code behind:

public AsyncCommand PreviousPageCommand { get; private set; }


            PreviousPageCommand = new AsyncCommand(
                () => ExecuteBackCommand(),
                param => param is bool canDo && canDo == true,
                continueOnCapturedContext: true,
                allowsMultipleExecutions: false);

 public bool BackEnabled => CanBackPage();

        private bool CanBackPage()
        {
            var ce = true;
            var p = _position;
            if (p > 0)
                ce = IsValid;
            else
                ce = false;

            TelemetryManager.WriteTrace($"Assessment: CanBackPage called for {p}, result={ce}");

            return ce;
        }

       public async Task ExecuteBackCommand()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
        {
            if (Volatile.Read(ref _isMovingBetweenPages))
            {
                TelemetryManager.WriteTrace("Assessment: moving, ExecuteBackCommand=no-op");
                return;
            }

            try
            {
                TelemetryManager.WriteTrace("Assessment: entered ExecuteBackCommand, setting moving=true");

                Volatile.Write(ref _isMovingBetweenPages, true);

                if (Position > 0)
                {
                    Position -= 1;
                }
            }
            finally 
            {
                TelemetryManager.WriteTrace("Assessment: exited ExecuteBackCommand, setting moving=false");
                Volatile.Write(ref _isMovingBetweenPages, false);
            }
        }
  • Version with issue: Latest f9p, latest Xamarin

  • Last known good version: Unknown

  • IDE: VS2019

  • Platform Target Frameworks: - iOS: Release build only!

  • Affected Devices: iPhone SE 2021 edition

@smalgin
Copy link
Contributor Author

smalgin commented Jan 12, 2023

At some point I let go of the Command entirely and managed the IsEnabled directly & called ExecuteBackCommand() directly from the Clicked event handler. Same result.
Eliminating all the other possiblities - it's something in the f9p:Button that glitches after repeated calls to IsEnabled?

Transient bugs are hard, so I am not placing the blame here. But this problem ate a week of my free time and it deserves to be documented :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant