xamarin.forms – 如何将已被键盘遮盖的编辑器滚动到视图中?

我正在设计Xamarin.Forms中的UI,以收集用户对我们应用程序的反馈.本页底部有一个Editor控件.在iPhone 4S和许多横向方向上,键盘完全掩盖了这种编辑器控件.在
Android上,这不是什么大问题,因为操作系统会自动滚动(虽然大小调整行为有点奇怪.)在iOS上,唯一类似于解决方案的东西非常不稳定.

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

我的布局很简单:

>在顶部,一个固定的导航栏,我不想滚动出视图.
>在其下方,180px高的图像代表应用程序的屏幕截图.
>在其下方,标签上包含时间戳等信息. (2-3行文字).
>在其下方,编辑器填充剩余的可用空间.

我已经包含了我在帖子底部尝试过的布局代码.我创建了一个包含图像,标签和编辑器的StackLayout.我把它放在ScrollView中.然后,我创建一个RelativeLayout并将导航栏放在左上方,ScrollView位于其下方.

点击编辑器时我想要发生的是键盘显示,如果它模糊了编辑器,则向上轻推布局以使编辑器可见.相反的是,似乎Xamarin通过键盘高度向上滚动布局加上一些看起来像键盘实用程序栏高度的边距.这使编辑向上推得如此之高,它被导航栏遮挡了.

我尝试了很多不同的调整,但我很茫然.我无法控制足够的ScrollView来获得我需要的行为.我已经看到了当编辑获得焦点时使用BoxView重新调整大小的建议,但为了使其工作得非常好我仍然必须挂钩iOS通知以获得适当的大小并且对编辑器的界限有相当深入的了解是.感觉不对.

有没有其他人在Xamarin.Forms上有解决方案?即使我不得不深入土着,我想要一个答案.

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

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;
        }
    }
}

最佳答案 我注意到的一件事是你将ScrollView(subLayout)添加到另一个ScrollView(_scroller).

另外,我在iOS上遇到了同样的问题,除了我的所有控件都在Grid中.只需将Grid放入单个ScrollView即可解决问题,而无需更改内容大小或类似内容.

点赞