所以我已经阅读了多篇关于这个问题的文章,但没有一篇对我的案例有用。
发生了什么:
当您通过单击一个条目来切换键盘时,在 Android 上,整个布局向上移动的幅度与键盘一样大。 iOS 只是将键盘呈现在顶部。这太糟糕了,尤其是对于我现在正在构建的聊天应用程序,完全隐藏了用户输入的条目编辑器字段。不可接受。
有一些解决方案(尽管我真的很想知道为什么 xamarin.ios 中没有包含这样一个基本的东西)
1.) 将您的布局放入滚动视图中。
这有效。只需将所有内容包装到滚动视图中,键盘就会将所有内容向上推。很棒,对吧?
不可以。在某些情况下,您无法将内容包装到滚动视图中:我的聊天就是一个例子。由于聊天视图本身就是滚动视图,因此外层不能是滚动视图。我的意思是,他们可以:但是你有两个相互叠加的滚动视图,导致滚动问题并且两者相互干扰。另外:像 height="180"
这样的值不再在滚动视图中工作,因为高度不是固定值。
2) 使用插件
有许多 nuget 插件应该可以使用,但在最新的 iOS 中它们不再适用了。有些仍然这样做,但在少数情况下(当按下 Enter 按钮以禁用键盘时)布局不能很好地向下滚动,留下空白空间。所以这些根本不起作用或不够好。
3) 添加当键盘被触发时膨胀的布局
这就是我作为一种解决方法所做的(这也不好):
在我的聊天输入字段所在的布局底部,我添加了以下布局:
<Grid Grid.Column="1" Grid.Row="2" x:Name="keyboardLayout" IsVisible="false" >
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
</Grid.RowDefinitions>
<BoxView BackgroundColor="Transparent"/>
</Grid>
是一个高度为300的固定布局,现在可以监听键盘变化事件了:
if (Device.RuntimePlatform == Device.iOS)
{
// Android does it well by itself, iOS is special again
var keyboardService = Xamarin.Forms.DependencyService.Get<IKeyboardService>();
keyboardService.KeyboardIsHidden += delegate
{
keyboardLayout.IsVisible = false;
};
keyboardService.KeyboardIsShown += delegate
{
keyboardLayout.IsVisible = true;
};
}
使用复杂的界面(如果有人需要,我会发布),我可以监听更改键盘事件。如果键盘可见,我只需用布局更新 UI。
这可行,但 300 的固定大小是一个问题。 直到今天,我仍然不知道 XAML 中的固定值是如何工作的(需要输入......!),对于较小的边距,它们似乎在每部手机上都相等,但对于较高的值(> 50),它们差异太大。>
所以我的解决方案对于较旧的 iPhone (6, 7) 来说已经足够好了。但在键盘和屏幕较长的新款 iPhone 上的条目之间留下了一点空白(11、12)。
总而言之:没有完美的解决方案。
我们需要什么
面对此问题的重要 xamarin 更新(不会很快发生),或者知道如何以像素为单位获取键盘高度的人,将其转换为 XAML 值,并根据所使用的手机填写它们.然后我的解决方案(第 3 条)将始终有效,无处不在(仍然是一种解决方法,但防弹)。
有没有人知道怎么做
a.) 以像素为单位获取显示键盘的高度
和(最重要的)
b.) 知道如何将像素转换为 Height="xxx"
感谢您参加我的 ted 演讲 ;)
答案 0 :(得分:0)
仅在 Xamarin.Forms iOS 项目中安装 Xamarin.IQKeyboardManager nuget 包。
在 AppDelegate.cs 中 Forms.init() 之前添加以下代码
IQKeyboardManager.SharedManager.Enable = true;
IQKeyboardManager.SharedManager.KeyboardDistanceFromTextField = 20;
当您点击进入时,它会像您在 Android 问题中提到的那样向上移动 UI。
答案 1 :(得分:0)
您可以先在共享代码中创建扩展网格的类。
public class KeyboardView: Grid{}
然后创建一个自定义渲染器来进行调整大小控制。
[assembly: ExportRenderer(typeof(KeyboardView), typeof(KeyboardViewRenderer))]
namespace KeyboardSample.iOS.Renderers
{
public class KeyboardViewRenderer : ViewRenderer
{
NSObject _keyboardShowObserver;
NSObject _keyboardHideObserver;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
RegisterForKeyboardNotifications();
}
if (e.OldElement != null)
{
UnregisterForKeyboardNotifications();
}
}
void RegisterForKeyboardNotifications()
{
if (_keyboardShowObserver == null)
_keyboardShowObserver = UIKeyboard.Notifications.ObserveWillShow(OnKeyboardShow);
if (_keyboardHideObserver == null)
_keyboardHideObserver = UIKeyboard.Notifications.ObserveWillHide(OnKeyboardHide);
}
void OnKeyboardShow(object sender, UIKeyboardEventArgs args)
{
NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
CGSize keyboardSize = result.RectangleFValue.Size;
if (Element != null)
{
Element.Margin = new Thickness(0, 0, 0, keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated
}
}
void OnKeyboardHide(object sender, UIKeyboardEventArgs args)
{
if (Element != null)
{
Element.Margin = new Thickness(0); //set the margins to zero when keyboard is dismissed
}
}
void UnregisterForKeyboardNotifications()
{
if (_keyboardShowObserver != null)
{
_keyboardShowObserver.Dispose();
_keyboardShowObserver = null;
}
if (_keyboardHideObserver != null)
{
_keyboardHideObserver.Dispose();
_keyboardHideObserver = null;
}
}
}
}
最后,在 KeyboardView 中添加内容。
你可以看看这个线程: