Прокрутка экрана вверх, когда клавиатура открыта на странице входа. Xamarin

Я работаю над Xamarin.Forms. У меня есть страница входа для этого я использую StackLayout с ScrollView. Код следующий

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="simpleListView.Pages.LoginPage">
<ContentPage.Content>
    <ScrollView Orientation="Vertical" x:Name="scroll">
    <StackLayout Padding="20">
        <Label Margin="20" HorizontalOptions="Center" Text="Login below" ></Label>
        <BoxView HeightRequest="150" Color="Accent"></BoxView>
        <Entry  Text="{Binding Email}" x:Name="txtEmail" Placeholder="Email"></Entry>
        <Entry Text="{Binding Password}" x:Name="txtPass" Placeholder="Paasword"></Entry>
        <Button x:Name="btnLogin" BackgroundColor="Blue" Text="Login" Command="{Binding SubmitCommand}"></Button>
    </StackLayout>
    </ScrollView>
</ContentPage.Content>
</ContentPage>

Но код выше не прокручивает раскладку вверх, когда клавиатура открыта и скрывает почти половину кнопки входа. Как реализовать прокрутку при открытой клавиатуре? Я не очень заинтересован в использовании пользовательских средств визуализации.

Смотрите страницу входа

1 ответ

Поскольку, насколько мне известно, нет хорошего способа получить фактическую высоту клавиатуры для Android с помощью DependencyService, использование этого scrollview является правильным подходом для начала, однако вам нужно настроить пользовательский интерфейс, который приведет к рендеры. "Я хочу классный пользовательский интерфейс, но я не заинтересован в пользовательских средствах визуализации" - это как "Я хочу водить, но я не интересуюсь колесами".

Однако, чтобы вам было легче, у меня есть код для пользовательского рендера, который дает желаемый результат:

Android

[assembly: ExportRenderer(typeof(ModernLogin), typeof(ModernLoginPageRenderer))]
namespace MyApp.Droid.Renderer
{
public class ModernLoginPageRenderer : PageRenderer
{
    public ModernLoginPageRenderer(Context context) : base(context)
    {

    }
    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);


        // Set SoftInput.AdjustResize for this window
        if (e.NewElement != null)
        {
            (this.Context as FormsApplicationActivity).Window.SetSoftInputMode(SoftInput.AdjustResize);             
        }
    }

    protected override void OnWindowVisibilityChanged([GeneratedEnum] ViewStates visibility)
    {
        // Revert to default SoftInputMode after moving away from this window
        if (visibility == ViewStates.Gone)
        {
            (this.Context as FormsApplicationActivity).Window.SetSoftInputMode(SoftInput.AdjustPan);
        }
        base.OnWindowVisibilityChanged(visibility);
    }

    protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
    {
        base.OnLayout(changed, left, top, right, bottom);
    }
}
}

IOS

[assembly: ExportRenderer(typeof(ModernLogin), typeof(ModernLoginPageRenderer))]

namespace MyApp.iOS.Renderer
{
public class ModernLoginPageRenderer : PageRenderer
{
    NSObject observerHideKeyboard;
    NSObject observerShowKeyboard;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var cp = Element as ModernLogin;
        if (cp != null)
        {
            foreach (var g in View.GestureRecognizers)
            {
                g.CancelsTouchesInView = true;
            }
        }
    }

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);

        observerHideKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardNotification);
        observerShowKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardNotification);
    }

    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);

        NSNotificationCenter.DefaultCenter.RemoveObserver(observerHideKeyboard);
        NSNotificationCenter.DefaultCenter.RemoveObserver(observerShowKeyboard);
    }

    void OnKeyboardNotification(NSNotification notification)
    {
        if (!IsViewLoaded) return;

        var frameBegin = UIKeyboard.FrameBeginFromNotification(notification);
        var frameEnd = UIKeyboard.FrameEndFromNotification(notification);

        var page = Element as ModernLogin;
        if (page != null)
        {
            var padding = page.Padding;
            page.Padding = new Thickness(padding.Left, padding.Top, padding.Right, padding.Bottom + frameBegin.Top - frameEnd.Top);
        }
    }
}
}

Убедитесь, что вы заменили имя "ModernLogin" именем класса вашей страницы входа. Если ваш LoginPage является обычным ContentPage, я бы порекомендовал создать новый класс, унаследованный от ContentPage.

Другие вопросы по тегам