Xamarin Forms iOS Button Click Event is not firing when keyboard is open (XF 4.3.0)

PathkonPathkon Member ✭✭
edited October 25 in Xamarin.Forms

Hey, I am posting a new question as a followup to this old question as instructed by @JoeHarvey_MSFT and @Charwaka

So, on iOS with an effect that affects the page layout, clicking on a button attached to the bottom of the page causes the entry unfocused event to block the button click event. This works correctly with a frame/label combo that emulates the button (thanks @AyalBelling ).

Below is sample XAML code (Use either BUTTON or FRAME CASE to check):

<Grid VerticalOptions="FillAndExpand">
    <ScrollView VerticalOptions="FillAndExpand">
        <StackLayout Padding="10, 20, 10, 60">
            <Label Text="Phone Number"
                   TextColor="{StaticResource PrimaryColorBase}"/>
            <Entry Placeholder="Add phone number..."
                   Text="{Binding PhoneNumber}"
                   PlaceholderColor="{StaticResource GrayColor}"
                   Keyboard="Telephone"/>

            <Label Text="Email"
                   TextColor="{StaticResource PrimaryColorBase}"/>
            <Entry Placeholder="Add email..."
                   Text="{Binding Email}"
                   PlaceholderColor="{StaticResource GrayColor}"
                   Keyboard="Email"/>
        </StackLayout>
    </ScrollView>

    <Grid HeightRequest="50"
           VerticalOptions="EndAndExpand">

         <!-- BUTTON CASE: Click fires unfocused event first and button click event is not firing on iOS -->
          <Button
            Text="Submit"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand"
            IsEnabled="{Binding IsDirty, Mode=TwoWay}"
            BackgroundColor="{StaticResource PrimaryColorBase}"
            TextColor="{StaticResource LightTextColor}"
            Margin="2"
            CornerRadius="4"
            Command="{Binding SubmitCommand}"/>

        <!-- FRAME CASE: Using frame instead of button to overcome button not firing click event when over the keyboard -->
        <Frame HasShadow="false"
               BackgroundColor="{StaticResource PrimaryColorBase}"
               OutlineColor="{StaticResource PrimaryColorBase}"
               IsEnabled="{Binding IsDirty, Mode=TwoWay}"
               Margin="2" Padding="0"
               CornerRadius="4"
               HorizontalOptions="FillAndExpand"
               VerticalOptions="FillAndExpand">
            <Frame.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding SubmitCommand}" NumberOfTapsRequired="1" />
            </Frame.GestureRecognizers>

            <Label TextColor="{StaticResource LightTextColor}" Text="Submit"
                   HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
        </Frame>

    </Grid>
</Grid>

iOS effect applied on page that changes page layout:

[assembly: ExportEffect(typeof(Company.Mobile.iOS.Effects.ResizeOnKeyboardEffect), "ResizeOnKeyboardEffect")]
namespace Company.Mobile.iOS.Effects
{
    public class ResizeOnKeyboardEffect : PlatformEffect
    {
        NSObject observerHideKeyboard;
        NSObject observerShowKeyboard;

        protected override void OnAttached()
        {
            if (Element is VisualElement)
            {
                observerHideKeyboard = UIKeyboard.Notifications.ObserveWillHide(OnKeyboardNotification);
                observerShowKeyboard = UIKeyboard.Notifications.ObserveWillShow(OnKeyboardNotification);
            }
        }

        protected override void OnDetached()
        {
            if (Element is VisualElement)
            {
                observerHideKeyboard.Dispose();
                observerShowKeyboard.Dispose();
            }
        }

        void OnKeyboardNotification(object sender, UIKeyboardEventArgs args)
        {
            var element = (VisualElement)Element;
            var frameBegin = args.FrameBegin;
            var frameEnd = args.FrameEnd;
            var bounds = element.Bounds;
            var newBounds = new Rectangle(bounds.Left, bounds.Top, bounds.Width, bounds.Height - frameBegin.Top + frameEnd.Top);
            element.Layout(newBounds);
        }
    }
}

Please feel free to file any official bug reports if needed, or maybe I could do it myself under your blessed guidance.

Thanks for your time and great efforts all!

Answers

Sign In or Register to comment.