16
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Xamarin.Formsでソフトウェアキーボードで入力欄が隠れないようにする2018

Last updated at Posted at 2018-01-26

はじめに

LINEのチャット画面のようにListViewの下に入力欄があるような画面で、なにも考えずに実装すると、画面が隠れるなど問題がいくつかあります。これの対策については素晴らしい過去の記事があります。Xamarin.Forms でソフトウェアキーボードが表示された時に画面が隠れないようにする

ただ、iOSで現在うまくいかないので最新版のベストプラクティスを載せておきます。Androidについては上記の記事を参考にしてください。

iOS

PageRendererをカスタムして対策します。

KeyboardResizingPageRenderer.cs
public class KeyboardResizingPageRenderer : PageRenderer
{
    NSObject _onKeyBoardShow;
    NSObject _onKeyBoardHide;
    nfloat _barHeight;
    double _initialHeight;
    bool _isInitial;

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

        _isInitial = true;

        if (NavigationController != null && NavigationController.TabBarController != null && NavigationController.TabBarController.TabBar != null)
        {
            _barHeight = NavigationController.TabBarController.TabBar.Frame.Height;
        }

        _onKeyBoardShow = UIKeyboard.Notifications.ObserveWillShow(OnKeyBoardShow);
        _onKeyBoardHide = UIKeyboard.Notifications.ObserveWillHide(OnKeyBoardHide);
    }

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

        if (_onKeyBoardShow != null)
        {
            NSNotificationCenter.DefaultCenter.RemoveObserver(_onKeyBoardShow);
        }

        if (_onKeyBoardHide != null)
        {
            NSNotificationCenter.DefaultCenter.RemoveObserver(_onKeyBoardHide);
        }
    }

    void OnKeyBoardShow(object sender, UIKeyboardEventArgs args)
    {
        var page = Element as ContentPage;

        if (_isInitial)
        {
            _initialHeight = page.Bounds.Height;
            _isInitial = false;
        }

        if (page != null)
        {
            var keyboardHeight = args.FrameEnd.Height - _barHeight;

            var pageFrame = Element.Bounds;

            // Padding変更じゃなしにページをLayoutTo
            Element.LayoutTo(new Rectangle(pageFrame.X, pageFrame.Y,
                                           pageFrame.Width, _initialHeight - keyboardHeight));
        }
    }

    void OnKeyBoardHide(object sender, UIKeyboardEventArgs args)
    {

        var page = Element as ContentPage;
        if (page != null)
        {
            var pageFrame = Element.Bounds;
            Element.LayoutTo(new Rectangle(pageFrame.X, pageFrame.Y,
                                           pageFrame.Width, _initialHeight));
        }
    }
}

こんな感じです。

キーボードの高さをとるのに苦労しましたが、UIKeyboardEventArgsのFrameEnd.Heightからとれます。変換候補の高さも考慮して上下してくれます。どうもTabBarを使っていると空白ができるようなのでTabBarの高さを引いてください。

16
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?