IOSのキーボードに関して問題があります。クロスプラットフォームのXamarinでチャットページを開発しています。このページには、ユーザーがメッセージに沿ってスクロールできるようにするscrollViewがあります。
IOSのキーボードに関して、エントリをカバーする一般的な問題があります。 iOSはページを自動的に上にスクロールしません。この問題を解決する簡単な解決策は、ページのコード全体をカバーするタグ「Scrollview」を配置することです。これは通常正常に機能します。ただし、私のページにはすでにスクロールビューがあります。したがって、スクロールビューを別のスクロールビュー内に配置すると、Androidでも動作が少しおかしくなります。 「メッセージビュー」をスクロールすることもあれば、ページ全体をスクロールすることもあります。
スクロールビュータグを使用しないiOSでのキーボードの問題を回避するための解決策はありますか?または、別のスクロールビュー内でスクロールビューを使用するための解決策はありますか?
助言がありますか?
前もって感謝します!
アプリにチャット機能を実装しようとしたときに、同じ問題が発生しました。解決策は、Entry
にカスタムレンダラーを使用し、キーボードイベントがトリガーされたときにそのマージンを調整することです。私はパターンに従いました この投稿で設定 。
この場合、Entry
をContentView
に埋め込むので、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
}
});
}
}
}
これに対処する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
から継承することです。
これがお役に立てば幸いです。
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)]