【问题标题】:How do I scroll an Editor that has been obscured by the keyboard into view?如何将已被键盘遮挡的编辑器滚动到视图中?
【发布时间】:2016-06-13 23:37:41
【问题描述】:

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

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

我的布局相当简单:

  • 在顶部,我不想滚动到视图之外的固定导航栏。
  • 在其下方是一个 180 像素高的图像,代表应用程序的屏幕截图。
  • 在其下方,带有时间戳等信息的标签。 (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;
        }
    }
}

【问题讨论】:

    标签: xamarin.forms


    【解决方案1】:

    我注意到的一件事是您正在将 ScrollView (subLayout) 添加到另一个 ScrollView (_scroller)。

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

    【讨论】:

      【解决方案2】:

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

      我的页面在 Android 上表现得如我所愿,所以我没有为此做任何具体的事情。

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

      这有点笨拙,有点尴尬,我希望能回来告诉我我尝试了另一种解决方案,比如 hvaughan3's,它奏效了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-27
        • 2019-04-01
        • 1970-01-01
        • 2022-01-08
        • 1970-01-01
        • 2011-11-12
        • 2014-03-27
        • 1970-01-01
        相关资源
        最近更新 更多