Bug 58988 - Calling Focus() on an Entry in iOS causes Entries to not be able to get focus when navigating to another page
Summary: Calling Focus() on an Entry in iOS causes Entries to not be able to get focus...
Status: CONFIRMED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 2.4.0
Hardware: PC Windows
: Normal major
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-08-23 21:24 UTC by Alma Jensen
Modified: 2017-08-25 18:06 UTC (History)
3 users (show)

Tags: entry, focus, ac
Is this bug a regression?: ---
Last known good build:


Attachments
Entry becoming not useable demo (293.91 KB, application/x-zip-compressed)
2017-08-23 21:24 UTC, Alma Jensen
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 58988 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description Alma Jensen 2017-08-23 21:24:12 UTC
Created attachment 24386 [details]
Entry becoming not useable demo

This was tested using the Nightly build available as of the afternoon of Aug 23rd.

I'm finding that on iOS if I call Focus() on an entry inside of an event handler that the control in question does get focus. However if I navigate away from the page with the Entry and then return to that page or go to any other page that has an Entry control those Entrys are no longer able to get focus, not even by tapping on them.  I can't type in them.

The sample project has 2 pages both with an Entry on them.  Navigate to either page.

In the unfocused event handler in the code behind I called this to demonstrate the bug.

private void HiddenEntry_Unfocused(object sender, FocusEventArgs e)
        {
            var entry = sender as Entry;
            entry.Focus();
        }

If you back out of either page1 or page2 you can then navigate to either of those pages and the Entry will be no more usable than a basic Label.
Comment 1 Paul DiPietro [MSFT] 2017-08-23 23:23:19 UTC
Thank you for checking against the nightly build. I'll mark this as confirmed for now and it also occurs on 2.3.4.
Comment 2 Alma Jensen 2017-08-24 15:20:13 UTC
Out of curiosity I tried changing the Entry to an Editor to see if I could find a work around.  
 -The first page works as expected
-back out and then go back to any page if you type nothing will show up
-Try backing out again and you'll get a null ref exception Here
public class Application
    {
        // This is the main entry point of the application.
        static void Main(string[] args)
        {
            // if you want to use a different Application Delegate class from "AppDelegate"
            // you can specify it here.
            UIApplication.Main(args, null, "AppDelegate");
        }
    }
Comment 3 Alma Jensen 2017-08-24 17:29:34 UTC
I tried something else looking for a work around and tried creating an effect.  It seems that calling BecomeFirstResponder() more than once during the life cycle of the page seems to cause this issue.  I'm leaving in some of my commented out test code so you can see some of the other things I've tried.

[assembly: ExportEffect(typeof(EntryFirstResponder), "EntryFirstResponder")]
namespace LOCMobile.iOS.Effects
{
    public class EntryFirstResponder : PlatformEffect
    {
        UITextField entry;
        protected override void OnAttached()
        {
            entry = Control as UITextField;
            if (entry == null)
                return;

            entry.BecomeFirstResponder();
            entry.AutocorrectionType = UITextAutocorrectionType.No;

            entry.EditingDidEnd += Entry_EditingDidEnd;
            //entry.Ended += Entry_Ended;
            //entry.EndedWithReason += Entry_EndedWithReason;
            //entry.EditingDidEndOnExit += Entry_EditingDidEndOnExit;
        }

        private void Entry_EditingDidEndOnExit(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Entry_EditingDidEndOnExit");
        }

        private void Entry_EndedWithReason(object sender, UITextFieldEditingEndedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Entry_EndedWithReason");
            ResetFirstResponder();
        }

        private void Entry_Ended(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Entry_Ended");
        }

        private void Entry_EditingDidEnd(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Entry_EditingDidEnd");
            ResetFirstResponder();
        }

        protected override void OnDetached()
        {
            //System.Diagnostics.Debug.WriteLine("Detaching First Responder");
            //if (entry != null)
            //{
            //    entry.EditingDidEnd -= Entry_EditingDidEnd;
            //    entry.Ended -= Entry_Ended;
            //    entry.EndedWithReason -= Entry_EndedWithReason;
            //    entry.EditingDidEndOnExit -= Entry_EditingDidEndOnExit;
            //}
        }

        private void ResetFirstResponder()
        {
            if(entry != null)
            {
                if (!entry.IsFirstResponder)
                    entry.BecomeFirstResponder();
            }
        }
    }
}
Comment 4 John Hardman 2017-08-25 17:53:19 UTC
As per related forum thread, try changing your code to:

    private void HiddenEntry_Unfocused(object sender, FocusEventArgs e)
    {
        var entry = sender as Entry;
        await Task.Run(async () =>
        {
            await Task.Delay(100);
            Device.BeginInvokeOnMainThread(() =>
            {
                entry.Focus();
            });
        });        
    }

(probably best to add try/catch around the Focus() call as well).

If that solves it, I'm not sure I would consider this a XF bug, but that's one for Xamarin folk to decide :-)
Comment 5 John Hardman 2017-08-25 18:06:50 UTC
Actually, after further thought, yes - I think it should be considered a XF bug, for the simple reason that the event is Unfocused (past tense) not Unfocusing (not yet complete).