我在Xamarin.Forms中设计用户界面以收集用户对我们应用程序的反馈。本页底部有一个Editor控件。在iPhone 4S和许多横向方向上,键盘完全掩盖了这种编辑器控件。在Android上,这不是什么大问题,因为操作系统会自动滚动(虽然大小调整行为有点奇怪。)在iOS上,唯一类似于解决方案的东西非常不稳定。
在原生iOS中,解决方案很简单:将视图包装在UIScrollView中,然后当键盘出现时为内容大小添加足够的空间并适当滚动。 Xamarin没有公开任何东西来控制ScrollView中的滚动位置,并且ContentSize是私有的,所以它就出来了。一些帖子(here和here)似乎表明ScrollView至少是解决方案的一部分。确实看来Xamarin有一些自动滚动行为,但它很奇怪。
我的布局相当简单:
我已经在我的帖子底部尝试了一个布局代码。我创建了一个包含图像,标签和编辑器的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;
}
}
}
答案 0 :(得分:1)
我注意到的一件事是您将ScrollView
(subLayout
)添加到另一个ScrollView
(_scroller
)。
此外,我在iOS上遇到了同样的问题,除了我的所有控件都在Grid
之内。只需将Grid
放入单个ScrollView
即可解决问题,而无需更改内容大小或类似内容。
答案 1 :(得分:1)
这个问题很长一段时间未得到答复,这就是我的所作所为。我不知道这是'答案',我很欣赏hvaughan3目前在这里的答案,如果我有空的话我会尝试。
我的页面表现得像我想要的Android,所以我没有做任何具体的事情。
所以我为iOS编写了使用通知UIKeyboardWillShow
和UIKeyboardWillHide
的特定代码。这些通知提供有关键盘将占用的边界的信息。因此,当我收到“显示”通知时,我会操纵我的布局,以便为我放置在键盘下方的那个大小的元素留出空间。当我收到“隐藏”通知时,我会重置布局。
这有点尴尬,有点尴尬,我希望回来的消息我尝试了另一种解决方案,比如hvaughan3,并且它有效。