Xamarin.forms 如何将被键盘遮挡的编辑器滚动到视图中?

Xamarin.forms 如何将被键盘遮挡的编辑器滚动到视图中?,xamarin.forms,Xamarin.forms,我正在用Xamarin.Forms设计一个用户界面,以收集用户对我们的应用程序的反馈。此页底部有一个编辑器控件。在iPhone4S上,在许多横向方向上,键盘完全遮蔽了编辑器控件。在Android上,这并不是什么大问题,因为操作系统会自动滚动(虽然大小调整的行为有点奇怪)。在iOS上,唯一类似于解决方案的东西是非常不可靠的 在本机iOS中,解决方案很简单:将视图包装在UIScrollView中,然后在键盘出现时为内容大小添加足够的空间并适当滚动。Xamarin没有公开任何东西来控制ScrollVi

我正在用Xamarin.Forms设计一个用户界面,以收集用户对我们的应用程序的反馈。此页底部有一个编辑器控件。在iPhone4S上,在许多横向方向上,键盘完全遮蔽了编辑器控件。在Android上,这并不是什么大问题,因为操作系统会自动滚动(虽然大小调整的行为有点奇怪)。在iOS上,唯一类似于解决方案的东西是非常不可靠的

在本机iOS中,解决方案很简单:将视图包装在UIScrollView中,然后在键盘出现时为内容大小添加足够的空间并适当滚动。Xamarin没有公开任何东西来控制ScrollView中的滚动位置,ContentSize是私有的,所以这就不存在了。一些帖子(和)似乎表明ScrollView至少是解决方案的一部分。看起来Xamarin确实有一些自动滚动的行为,但是。。。好奇

我的布局相当简单:

  • 在顶部,是一个固定的导航栏,我不想滚动到视图之外
  • 下面是一个180像素高的图像,代表应用程序的屏幕截图
  • 下面是一个标签,上面有时间戳等信息。(2-3行文字)
  • 下面是编辑器,填充剩余的可用空间
我在文章的底部包含了我尝试过的布局代码。我创建了一个包含图像、标签和编辑器的StackLayout。我把它放在滚动视图中。然后,我创建了一个RelativeLayout,并将导航栏放在左上角,下面是ScrollView

我希望在点击编辑器时显示键盘,如果键盘遮挡了编辑器,则向上推动布局以使编辑器可见。相反,Xamarin似乎将布局向上滚动键盘高度加上一些看起来像键盘工具条高度的边距。这会将编辑器向上推得太高,以至于导航栏无法将其遮挡

我尝试了很多不同的调整,但我不知所措。我无法控制足够的ScrollView以获得所需的行为。我看到过一些建议,当编辑器获得焦点时,使用调整大小的BoxView,但为了让它工作得很好,我仍然需要连接到iOS通知中,以获得适当的大小,并对编辑器的边界有相当深入的了解。感觉不对

其他人对Xamarin.Forms有解决方案吗?即使我必须学习母语,我也想要一个答案

(这是一个演示问题的布局示例,因为我正在调试,所以有一点奇怪的结构。时髦的颜色也是布局调试的遗留物。)


我注意到的一件事是,您正在将一个
滚动视图
子布局
)添加到另一个
滚动视图
\u scroller


此外,我在iOS上也遇到了同样的问题,只是我的所有控件都在
网格中。只需将
网格
放入一个
滚动视图
即可解决问题,而无需更改内容大小或诸如此类的内容。

这个问题很久没有得到回答,下面是我所做的。我不知道这是“答案”,我非常感谢hvaughan3目前给出的答案,如果有时间,我会尝试一下

我的页面在Android上的表现就像我想要的一样,所以我没有为此做任何具体的事情

因此,我为使用通知的iOS编写了特定代码
UIKeyboardWillShow
UIKeyboardWillHide
。这些通知提供有关键盘将占用的边界的信息。因此,当我收到“显示”通知时,我会操纵我的布局,以便在键盘下方留出足够的空间来放置大小相同的元素。当我收到“隐藏”通知时,我会重置布局

这很简陋,有点尴尬,我希望能带着消息回来,我尝试了另一种解决方案,比如hvaughan3,它成功了

using System;
using Xamarin.Forms;

namespace TestScroll
{
    public class MainPage : ContentPage {
        public MainPage() {
            InitializeComponent();
        }

        private ScrollView _scroller;

        protected void InitializeComponent() {
            var mainLayout = new RelativeLayout();

            var navbar = new Label() {
                BackgroundColor = Color.Blue,
                TextColor = Color.White,
                Text = "I am the Nav Bar",
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.StartAndExpand
            };

            var subLayout = new ScrollView() {
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand
            };
            _scroller = subLayout;

            var subStack = new StackLayout();
            subStack.Spacing = 0;
            subLayout.Content = subStack;

            var image = new BoxView() {
                Color = Color.Green,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.Fill,
                HeightRequest = 300
            };
            subStack.Children.Add(image);

            var infoLabel = new Label() {
                BackgroundColor = Color.Blue,
                TextColor = Color.Black,
                Text = "Timestamp!\r\nOther stuff!",
                VerticalOptions = LayoutOptions.Start
            };
            subStack.Children.Add(infoLabel);

            var editor = new Editor() {
                VerticalOptions = LayoutOptions.FillAndExpand
            };
            subStack.Children.Add(editor);

            mainLayout.Children.Add(navbar, 
                Constraint.Constant(0), 
                Constraint.Constant(20), 
                Constraint.RelativeToParent((parent) => parent.Width),
                Constraint.Constant(70));

            mainLayout.Children.Add(subLayout,
                Constraint.Constant(0),
                Constraint.RelativeToView(navbar, (parent, view) => navbar.Bounds.Bottom),
                Constraint.RelativeToParent((parent) => parent.Width),
                Constraint.RelativeToView(navbar, TestConstraint));

            Content = mainLayout;
        }

        private double TestConstraint(RelativeLayout parent, View view) {
            double result = parent.Height - view.Bounds.Height;
            Console.WriteLine ("Lower stack height : {0}", result);
            Console.WriteLine ("Scroll content size: {0}", _scroller.ContentSize);
            return result;
        }
    }
}