我在iOS上遇到键盘问题.我正在跨平台的Xamarin上开发一个聊天页面,这个页面有一个scrollView,使用户可以沿着消息滚动.
iOS上的键盘存在一个常见问题,它涵盖了条目.iOS不会自动向上滚动页面.要解决这个问题,一个简单的解决方案是将标签"Scrollview"覆盖整个页面代码.这通常很好.但是,我的页面里面已经有了一个scrollview.因此,当我将scrollview放在另一个scrollview中时,即使在Android上,行为也有点疯狂.有时它会滚动"消息视图",有时会滚动整个页面.
有一个解决方案可以避免iOS上没有使用scrollview标签的键盘问题吗?或者有一个解决方案在另一个scrollview中使用scrollview?
有什么建议?
先感谢您!
处理此问题的一种方法是自定义页面渲染器,在键盘出现时向上滚动整个页面.
以下是一些示例代码.我假设您只想在需要它的页面上执行此操作,因此首先在Forms PCL(可移植类库)项目中创建一个空的子类,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(); } } }
由于此渲染器实际上在键盘显示和隐藏时向上和向下滚动整个本机页面,因此无论您如何在Forms Xaml中布局页面都无关紧要.重要的是您的表单页面继承自KeyboardInputContentPage
.
我希望这有帮助!
我在尝试在我们的应用程序中实现聊天功能时遇到了同样的问题.解决方案是使用自定义渲染器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 } }); } } }