web-dev-qa-db-ja.com

ページにXamarinフォームのスクロールビューが既にある場合に、iOSキーボードのオーバーラップエントリを処理する方法

IOSのキーボードに関して問題があります。クロスプラットフォームのXamarinでチャットページを開発しています。このページには、ユーザーがメッセージに沿ってスクロールできるようにするscrollViewがあります。

IOSのキーボードに関して、エントリをカバーする一般的な問題があります。 iOSはページを自動的に上にスクロールしません。この問題を解決する簡単な解決策は、ページのコード全体をカバーするタグ「Scrollview」を配置することです。これは通常正常に機能します。ただし、私のページにはすでにスクロールビューがあります。したがって、スクロールビューを別のスクロールビュー内に配置すると、Androidでも動作が少しおかしくなります。 「メッセージビュー」をスクロールすることもあれば、ページ全体をスクロールすることもあります。

スクロールビュータグを使用しないiOSでのキーボードの問題を回避するための解決策はありますか?または、別のスクロールビュー内でスクロールビューを使用するための解決策はありますか?

助言がありますか?

前もって感謝します!

10
Artur Quirino

アプリにチャット機能を実装しようとしたときに、同じ問題が発生しました。解決策は、Entryにカスタムレンダラーを使用し、キーボードイベントがトリガーされたときにそのマージンを調整することです。私はパターンに従いました この投稿で設定

この場合、EntryContentViewに埋め込むので、ViewRendererから継承してContentViewを調整します。状況に応じて、継承するレンダラーは異なる場合があります。ただし、ほとんどの場合、マージンをキーボードの高さにリセットできるはずです。

using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using HBIClientFacingApp;
using HBIClientFacingApp.iOS;

[Assembly:ExportRenderer( typeof(ChatViewWithEntry), typeof(ChatEntryRenderer))]
namespace YourNameSpace.iOS
{
    public class ChatEntryRenderer : ViewRenderer //Depending on your situation, you will need to inherit from a different renderer
    {
        public ChatEntryRenderer()
        {   
            UIKeyboard.Notifications.ObserveWillShow ((sender, args) => {

                if (Element != null)
                {
                    Element.Margin = new Thickness(0,0,0, args.FrameEnd.Height); //Push the entry up to keyboard height when keyboard is activated
                }
            });

            UIKeyboard.Notifications.ObserveWillHide ((sender, args) => {

                if (Element != null)
                {
                       Element.Margin = new Thickness(0); //set the margins to zero when keyboard is dismissed
                }

            }); 
        }

    }
}
9

これに対処する1つの方法は、キーボードが表示されたときにページ全体を上にスクロールする カスタムページレンダラー です。

これを行うためのサンプルコードを次に示します。これは、それを必要とするページでのみ実行したいと思うので、最初にForms PCL(Portable Class Library)プロジェクトで、ContentPageの空のサブクラスを作成します。 KeyboardInputContentPage(またはあなたが好きなもの)と呼ばれる:

public class KeyboardInputContentPage : ContentPage {}

次に、この機能が必要な実際のページのKeyboardInputContentPageから継承します。私のテストでは、これをTestKeyboardInputContentPageと呼びました。

public partial class TestKeyboardInputContentPage : KeyboardInputContentPage
{ 
    public TestKeyboardInputContentPage()
    {
        InitializeComponent();
    }
    //etc
}

そして、カスタムページレンダラーコード。これはiOSアプリプロジェクトに当てはまります。

[Assembly: ExportRenderer(typeof(KeyboardInputContentPage), typeof(ContentPageRenderer))]
namespace MyAppName.iOS
{
    public class ContentPageRenderer : PageRenderer
    {   
        private NSObject keyBoardWillShow;
        private NSObject keyBoardWillHide;
        private nfloat scrollAmout;
        private double animDuration;
        private UIViewAnimationCurve animCurve;
        private bool keyboardShowing;

        public override void ViewDidLoad()
        {

            base.ViewDidLoad();

            keyBoardWillShow = UIKeyboard.Notifications.ObserveWillShow(KeyboardWillShow);

            keyBoardWillHide = UIKeyboard.Notifications.ObserveWillHide(KeyboardWillHide);
        }

        void KeyboardWillShow(object sender, UIKeyboardEventArgs args)
        {
            if (!keyboardShowing)
            {
                keyboardShowing = true;
                animDuration = args.AnimationDuration;
                animCurve = args.AnimationCurve;

                var r = UIKeyboard.FrameBeginFromNotification(args.Notification);
                scrollAmout = r.Height;
                ScrollTheView(true);
            }
        }

        void KeyboardWillHide(object sender, UIKeyboardEventArgs args)
        {
            if (keyboardShowing)
            {
                keyboardShowing = false;
                animDuration = args.AnimationDuration;
                animCurve = args.AnimationCurve;

                var r = UIKeyboard.FrameBeginFromNotification(args.Notification);
                scrollAmout = r.Height;
                ScrollTheView(false);
            }
        }

        private void ScrollTheView(bool scale)
        {
            UIView.BeginAnimations(string.Empty, IntPtr.Zero);
            UIView.SetAnimationDuration(animDuration);
            UIView.SetAnimationCurve(animCurve);

            var frame = View.Frame;

            if (scale)
                frame.Y -= scrollAmout;
            else
                frame.Y += scrollAmout;
            View.Frame = frame;
            UIView.CommitAnimations();
        }
    }
}

このレンダラーは、キーボードが表示および非表示になると、実際にはネイティブページ全体を上下にスクロールするため、FormsXamlでページをどのようにレイアウトするかは重要ではありません。重要なのは、フォームページがKeyboardInputContentPageから継承することです。

これがお役に立てば幸いです。

8

IOSの場合、このプラグインを使用できます(iOSプロジェクトに追加します): https://github.com/paulpatarinski/Xamarin.Forms.Plugins/tree/master/KeyboardOverlap

Android LoadApplication(new App());の後にMainActivityに次の文字列を追加します。

App.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().
UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

// this can also be done by adding WindowSoftInputMode = SoftInput.AdjustResize as shown below:
 [Activity(WindowSoftInputMode = SoftInput.AdjustResize)]
4
ajaysinh rajput