【问题标题】:Xamarin.Forms IOS softkeyboard hides layoutXamarin.Forms IOS 软键盘隐藏布局
【发布时间】:2021-08-27 10:18:59
【问题描述】:

所以我已经阅读了关于这个问题的多篇文章,但没有一篇对我的案例有用。

会发生什么:

当您通过单击一个条目来切换键盘时,在 Android 上,整个布局会随着键盘的大小向上移动。 iOS 只是将键盘呈现在顶部。这太糟糕了,尤其是对于我现在正在构建的聊天应用程序,它完全隐藏了用户键入的条目编辑器字段。不可接受。

有一些解决方案(尽管我真的很想知道为什么这样一个基本的东西还没有包含在 xamarin.ios 中)

1.) 将您的布局放入滚动视图中。

这行得通。只需将所有内容包装到滚动视图中,键盘就会将所有内容向上推。太好了,对吧? 不。在某些情况下,您不能将内容包装到滚动视图中:我的聊天就是一个例子。由于聊天视图本身就是滚动视图,因此外层不能是滚动视图。我的意思是,他们可以:但是你有两个滚动视图在彼此之上,导致滚动问题并且相互干扰。另外:像height="180" 这样的值在滚动视图中不再起作用,因为高度不是固定值。

2) 使用插件

有许多 nuget 插件应该可以工作,但在最新的 iOS 上它们就不再适用了。有些仍然这样做,但在少数情况下(当按下回车按钮以禁用键盘时)布局不能很好地向下滚动而留下空白区域。所以这些根本不起作用或不够好。

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 演讲 ;)

【问题讨论】:

    标签: ios xaml xamarin.forms


    【解决方案1】:

    仅在 Xamarin.Forms iOS 项目中安装 Xamarin.IQKeyboardManager nuget 包。

    在 AppDelegate.cs 中 Forms.init() 之前添加以下代码

    IQKeyboardManager.SharedManager.Enable = true;
    IQKeyboardManager.SharedManager.KeyboardDistanceFromTextField = 20;
    

    当您单击条目时,它会将 UI 向上移动,正如您在 Android 问题中提到的那样。

    【讨论】:

    • 我知道为什么,但该插件目前工作正常。我不想在前一天晚上赞美前一天,但我会检查一下。
    • 所以它似乎运行良好,但是:它禁用了页面上的所有其他内容。这意味着如果您键入聊天消息然后点击发送,您必须单击它两次(一次用于关闭键盘,一次用于发送消息):(
    • 您可以更改文本字段和键盘之间的距离。我刚刚在上面的代码中更新了这个。试试添加这个。希望这会奏效。
    • 嗯,这增加了到键盘的距离,但与用户仍然必须单击两次无关:一次禁用键盘,一次实际使用按钮。 (按钮从一开始就没有隐藏)
    【解决方案2】:

    您可以先在共享代码中创建扩展网格的类。

    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 中添加内容。

    你可以看看这个帖子:

    adjust and move the content of a page up slightly when the keyboard appears in an Entry control Xamarin Forms

    【讨论】:

      猜你喜欢
      • 2016-03-10
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多