Xamarin Forms iOS Button Click Event is not Firing when the keyboard is open

Hi All,

I have a login view with a UserName & Password field and a Login Button.

While entering UserName & Password the keyboard opens and when i click login now, the click event is not getting called. Only the keyboard is getting hidden. Now when i click login it works.

Seems like, if the keyboard is open and a button is pressed, it takes it as a screen touch event and closes the keyboard, but doesn't call the click event.

This is happening after i upgraded to the latest version of Xamarin.

Please advise.

Thanks,
Manoj

Answers

  • GeraldVersluisGeraldVersluis NLUniversity ✭✭✭✭
    edited June 2016

    Hi Manoj,

    Please share some code as to how you've build up your screen and the event is handled etc.

    Also you say;

    This is happening after i upgraded to the latest version of Xamarin.

    What version is it exactly?

  • ArturShamsutdinovArturShamsutdinov USMember, University

    I'm facing same issue.

  • ArturShamsutdinovArturShamsutdinov USMember, University

    Looks like this issue can be reproduced if button is under the keyboard and scrolled up. Sample project attached.

  • ManojReddy.8431ManojReddy.8431 USMember ✭✭

    <Entry x:Name="TxtUserName" StyleId="LoginUsername" Placeholder="Username" Text="{Binding Username}" BackgroundColor="{x:Static helpers:MyColors.White}" TextColor="{x:Static helpers:MyColors.Black}" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Focused="KeyboardVisible" Unfocused="KeyboardHidden"/> <Entry x:Name="TxtPassword" StyleId="LoginPassword" IsPassword="true" Placeholder="Password" Text="{Binding Password}" BackgroundColor="{x:Static helpers:MyColors.White}" TextColor="{x:Static helpers:MyColors.Black}" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Focused="KeyboardVisible" Unfocused="KeyboardHidden" Completed="PasswordCompleted"/> <Button StyleId="LoginButton" Text="Login" BackgroundColor="{x:Static helpers:MyColors.Teal}" TextColor="{x:Static helpers:MyColors.DarkBlue}" FontSize="Large" FontAttributes="Bold" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Clicked="LoginPressed"/>

    I found the root cause. It is because of the Unfocused event.

    When i enter user name and password and click Login, the unfocused event of TxtPassword is called and not the LoginPressed event

  • adamkempadamkemp USInsider, Developer Group Leader mod

    I don't think it's because of the unfocused event. That event is fired when the text field loses focus, regardless of how it lost focus. What's probably happening here is that Forms sets up a tap gesture to handle dismissing the keyboard when you tap anywhere outside the keyboard. That is stealing the touch that would go to the button. They do that at a pretty low level (I think the PageRenderer does it, if I recall correctly), and in a pretty heavy-handed way. It's caused numerous problems judging by questions I've seen on the forums. See this discussion for example. Fortunately you now have access to the source code so you can maybe see more detail about how and why they are doing things that I couldn't see at the time.

  • AyalBellingAyalBelling GBUniversity ✭✭

    I've reproduced that the Unfocused event is blocking the Clicked on my adjacent button. XAML below. This horizontal stack is at the bottom of a message page so I move the Entry and Button up by the height of the keyboard when editor has focus and back down when it loses focus.

    With the Unfocused event on the Entry, the Clicked on the Button doesn't fire. When the Unfocused event is removed from the Entry, the Clicked does fire. Go figure. Issue also started for me when I upgraded Xamarin.iOS to 9.8.0.323.

            <StackLayout Orientation="Horizontal" Padding="5" Spacing="5" VerticalOptions="End">
                <Frame BackgroundColor="White" OutlineColor="White" HasShadow="false" Padding="0" HorizontalOptions="FillAndExpand">
                    <Frame.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnEditorTapped" NumberOfTapsRequired="1" />
                    </Frame.GestureRecognizers>
    
                    <Editor x:Name="MessageEditor" Keyboard="Text" HorizontalOptions="FillAndExpand" VerticalOptions="Start" TextColor="Gray" BackgroundColor="Transparent"
                        HeightRequest="{x:Static local:App.messagePageEditorHeight}" FontSize="{x:Static local:App.fontEditor}" Focused="EditorFocused" Unfocused="EditorUnfocused" />
                </Frame>
    
                <ActivityIndicator x:Name="SendingIndicator" WidthRequest="{x:Static local:App.messagePageEditorHeight}"
                    HeightRequest="{x:Static local:App.messagePageEditorHeight}" IsVisible="false" IsRunning="false" />
    
                <local:ButtonCustomFont x:Name="SendButton" FontFamily="OpenSans-Semibold" BorderColor="{x:Static local:App.toolbarColor}" BorderWidth="0"
                    TextColor="Gray" BorderRadius="5" Text=">" BackgroundColor="White"
                    FontSize="{x:Static local:App.fontLarge}" Clicked="SendClicked" WidthRequest="{x:Static local:App.messagePageEditorHeight}" />
            </StackLayout>
    
  • BGardnerBGardner USUniversity ✭✭

    Has there been any update to this (other than using a hacky solution of a frame)? Also has a bug been reported for this?

  • AndyMartin.6838AndyMartin.6838 USMember ✭✭

    I think as long as you use a TGR instead of an actual button, it will work. It's sad how many things break in Forms so often.

  • alaskanroguealaskanrogue USMember ✭✭✭

    I have a single cross platform XF view with a 9 row grid. The planned user experience is have the user respond to a top - down query, one row appearing at a time, the content driven by the previous rows' input. The input controls per row vary. The first row are buttons. The second row is a list view. The third row is again buttons.

    On WinPhone 8.1, things are fine through out the 9 nine row sequence. However on iOS, the buttons on the third row don't work; the "Clicked" event is not firing. The first row buttons fire and make the second row visible. The second row list view gets its event and make the third row visible, but its buttons are dead. On Droid, the third row works fine but the forth row fails to display its buttons and nothing seems active.

    I replaced the buttons in the third row with images with GestureRecognizers enable. Same results.

    Do I need to reset the event subsystem to listen for events since I didn't move to a new view? Do I need to refresh the whole view after each event? Other ideas?

  • alaskanroguealaskanrogue USMember ✭✭✭

    When is the footprint (x1,y1,x2,y2) for the interaction with a control set? At IsEnabled? IsVisible?

    What happens if another control steps on that footprint and then steps off after the footprint is originally set? Do one of the above methods need to be recalled? A different method?

  • alaskanroguealaskanrogue USMember ✭✭✭

    I resolved the issue of images on Droid, which was a path issue, and everything now works like the WinPhone version.

    But on the iOS version, the third row buttons, when made visible, still don't have active "Clicked" events triggers. I even tried resetting the method to be used after being made visible. Interesting though is the "Cancel" button at the bottom of the page is operational.

    Is there a trace for touch events that can be activated?

  • KalyanMungiKalyanMungi USMember ✭✭

    Just add this code in your page renderer, Override the ViewDidLoad method and the following line

    foreach (var g in View.GestureRecognizers) { //If a gesture recognizer recognizes its gesture, it unbinds the remaining touches of that gesture from their view. //If a u recognizer doesn’t recognize its gesture, the view receives all touches in the multi-touch sequence. g.CancelsTouchesInView = true; }

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Absolutely do not do that. That is a terrible idea.

  • ChrisFouldsChrisFoulds GBMember ✭✭

    Any update on this, it's a year later and this issue still exists.

  • BhaurajBiradar.9064BhaurajBiradar.9064 USMember ✭✭✭

    Any updates for ios?

  • BhaurajBiradar.9064BhaurajBiradar.9064 USMember ✭✭✭

    Any updates in iOS?

  • BhaurajBiradar.9064BhaurajBiradar.9064 USMember ✭✭✭

    Hi, I fixed the issue with HitTest in iOS.. Everything working fine :)

  • itransititransitransititrans USMember

    Bhauraj Biradar could you please share some details about your solution? Thank you!

  • BhaurajBiradar.9064BhaurajBiradar.9064 USMember ✭✭✭
    edited July 2017

    @itransititrans - I Created cutsom layout(using StackLayout or Grid) and in that layout i have all entry and button. On layout rendrerer i am doing hit test and finding out the button is clicked or not, if its button is clicked setting flag which will be tracked in Custom Entry On property element changed like below,

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == VisualElement.IsFocusedProperty.PropertyName)
            {
                if (Control != null)
                {
                    Control.ShouldEndEditing =
                        (UITextField textField) =>
                        {
                            Control.ResignFirstResponder();
                            //do here coding first check flag and then fire an event
                            return true;
                        };
                }
            }
            base.OnElementPropertyChanged(sender, e);
        }
    

    Please let me know if you need more information

  • Joel.7378Joel.7378 USMember ✭✭

    @BhaurajBiradar - I'd love to see the full code you used to fix this issue. I'm not quite wrapping my head around what you're doing there. Can you also post the code you actually wrote in place of the comment "//do here coding first check flag and then fire an event", as well as the custom renderer you wrote for the containing stacklayout? Thanks!

  • SanjeevKumarSanjeevKumar USMember ✭✭

    @BhaurajBiradar.9064 i am attaching sample project in which i can reproduce the above bug, can you please make the code changes to the attached project and post it here. you can reproduce the bug by running app in ipad in landscape mode

  • DevReyzDevReyz Member

    I am also facing the same issue. Xamarin.Forms iOS project

    i have an editor which is subscribed to the unfocused event and a button which has a command property bound to a send method in my viewmodel.
    When i type on the editor and press the button, the "unfocused" event of the editor is fired BUT not firing the command which is bound to the button. It is working well in Android but not in iOS.

  • Anurag2aprAnurag2apr USMember ✭✭

    Hi Everyone,

    I created a Custom layout using Grid and in that layout i have all Entry and Button as child elements. On layout renderer for iOS i did a hit test to check if the keyboard hides automatically and the Button event is triggered. For this is work, we require the Render the Parent view first and then Child Control.

    Parent:

    [assembly: ExportRenderer(typeof(CcGrid), typeof(CcGridRenderer))]
    namespace TessaLink.iOS
    {
    public class CcGridRenderer : VisualElementRenderer
    {
    public override UIView HitTest(CoreGraphics.CGPoint point, UIEvent uievent)
    {
    UIView view = base.HitTest(point, uievent);
    if(view.GetType()== typeof(UIButton)){
    CcTextBoxRenderer.IsButtonClickedWithVisibleKeyboard = true;
    }
    return view;
    }
    }
    }

    Child Control:

    [assembly: ExportRenderer(typeof(CcTextBox), typeof(CcTextBoxRenderer))]
    namespace TessaLink.iOS
    {
    public class CcTextBoxRenderer : EntryRenderer
    {
    public static bool IsButtonClickedWithVisibleKeyboard;

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
    
            if (Control != null) {
                //Control.BorderStyle = UITextBorderStyle.None;
            }
        }
    
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if(e.PropertyName == VisualElement.IsFocusedProperty.PropertyName){
                if(Control != null){
                    Control.ShouldEndEditing = 
                        (UITextField textField) =>
                    {
                        Control.ResignFirstResponder();
                        //do here coading first check flag and then fire an event. 
    
                        if(IsButtonClickedWithVisibleKeyboard){
                            IsButtonClickedWithVisibleKeyboard = false;
                            return false;
                        }else{
                            return true;
                        }
                    };
                }
            }
            base.OnElementPropertyChanged(sender, e);
        }
    }
    

    }

  • Anurag2aprAnurag2apr USMember ✭✭

    Hi Everyone, I created a Custom layout using Grid and in that layout i have all Entry and Button as child elements. On layout renderer for iOS i did a hit test to check if the keyboard hides automatically and the Button event is triggered. For this is work, we require the Render the Parent view first and then Child Control.

    Parent Layout:

    [assembly: ExportRenderer(typeof(CcGrid), typeof(CcGridRenderer))]
    namespace TessaLink.iOS
    {
    public class CcGridRenderer : VisualElementRenderer
    {
    public override UIView HitTest(CoreGraphics.CGPoint point, UIEvent uievent)
    {
    UIView view = base.HitTest(point, uievent);
    if(view.GetType()== typeof(UIButton)){
    CcTextBoxRenderer.IsButtonClickedWithVisibleKeyboard = true;
    }
    return view;
    }
    }
    }

    Child Control

    [assembly: ExportRenderer(typeof(CcTextBox), typeof(CcTextBoxRenderer))]
    namespace TessaLink.iOS
    {
    public class CcTextBoxRenderer : EntryRenderer
    {
    public static bool IsButtonClickedWithVisibleKeyboard;

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
    
            if (Control != null) {
                //Control.BorderStyle = UITextBorderStyle.None;
            }
        }
    
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if(e.PropertyName == VisualElement.IsFocusedProperty.PropertyName){
                if(Control != null){
                    Control.ShouldEndEditing = 
                        (UITextField textField) =>
                    {
                        Control.ResignFirstResponder();
                        //do here coading first check flag and then fire an event. 
    
                        if(IsButtonClickedWithVisibleKeyboard){
                            IsButtonClickedWithVisibleKeyboard = false;
                            return false;
                        }else{
                            return true;
                        }
                    };
                }
            }
            base.OnElementPropertyChanged(sender, e);
        }
    }
    

    }

  • lucidBrotlucidBrot Member ✭✭
    edited April 24

    This is still an issue in 2019. My frame's TapGestureRecognizer is triggered but my button's ClickGestureRecognizer and TapGestureRecognizer are not.


    It turns out that setting Clicked from XAML still does work for the Buttons!

  • PathkonPathkon Member ✭✭

    The issue still exists for iOS as of today. Using Xamarin.Forms 4.3.0.908675

    Any updates?

  • JoeHarvey_MSFTJoeHarvey_MSFT Member, Xamarin Team Xamurai

    Given that this is a very old thread I don't think anything is going to be fixed by posting here. If anyone would like to submit a ticket to Microsoft regarding this issue, then myself or one of my colleagues would be more then happy to find out what is happening and either fix the issue or bring it to the attention of the Dev Team.

    Microsoft Support link. Free support for all Xamarin Developers
    https://support.microsoft.com/en-us/supportforbusiness/productselection?sapId=211dd84f-3474-c3c5-79bf-66db630c92a6

  • CharwakaCharwaka INMember ✭✭✭✭✭

    @Pathkon said:
    The issue still exists for iOS as of today. Using Xamarin.Forms 4.3.0.908675

    Any updates?

    can you please provide a sample project ,so we can test it ?

  • PathkonPathkon Member ✭✭
    edited October 25

    I have created a new question as a followup after @JoeHarvey_MSFT suggestion
    link here

Sign In or Register to comment.