Xamarin Forms中的滚动编辑器进入视图

Joh*_*son 9 xamarin.ios ios xamarin xamarin.forms

使用Xamarin Forms,考虑下面的Xaml.

<StackLayout VerticalOptions="FillAndExpand">
   <Image x:Name="cameraImage" Source="camera.png" />
   <Label Text="Describe the image" />
   <Editor />
   <Button Text="Save" />
 </StackLayout>
Run Code Online (Sandbox Code Playgroud)

这将呈现图像,编辑器和保存按钮.图像的图像比例为4x3,覆盖了可用屏幕高度的三分之一.编辑器呈现如下.

问题是键盘覆盖了iOS中的编辑器.通常是标准的iOS问题.

问题是:Xamarin Forms处理这个问题的方法是什么?

谢谢

//约翰

Fal*_*lko 11

我在编写一个小型聊天应用程序时偶然发现了这个问题,该应用程序基本上包含一个可滚动的消息列表,一个文本条目和一个发送按钮:

以前发布的解决方案的问题是您需要嵌套两个滚动视图,这是Xamarin.Forms文档不推荐的.为了防止键盘隐藏条目,我发现了以下黑客攻击:

placeholder在主堆栈布局的末尾添加了一个.根据条目是否被聚焦(即键盘是否可见),占位符的高度设置为0或键盘高度.

        // HACK: make entry visible when keyboard open
        var placeholder = new BoxView {
            HeightRequest = 0,
        };
        entry.Focused += (sender, e) => placeholder.HeightRequest = 210;
        entry.Unfocused += (sender, e) => placeholder.HeightRequest = 0;

        Content = new StackLayout {
            VerticalOptions = LayoutOptions.Fill,
            Padding = 5,
            Children = {
                whoTable,
                messageScrollView,
                new StackLayout {
                    Orientation = StackOrientation.Horizontal,
                    VerticalOptions = LayoutOptions.End,
                    HeightRequest = 70,
                    Children = {
                        entry,
                        sendButton,
                    },
                },
                placeholder,
            },
        };
Run Code Online (Sandbox Code Playgroud)

当然,这并不完美.特别是硬编码的键盘高度应该更优雅地实现.也许你应该只在iOS上应用它,而不是在Android上.


Ste*_*oix 7

要使用Xamarin.Forms自动滚动编辑器和条目,您通常只需将View(在本例中为StackLayout)打包到ScrollView中:

<ScrollView>
    <StackLayout VerticalOptions="FillAndExpand">
        <Image x:Name="cameraImage" Source="camera.png" />
        <Label Text="Describe the image" />
        <Editor />
        <Button Text="Save" />
    </StackLayout>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

这就是它应该如何工作,但截至今天(2014年6月),有一个错误阻止它与编辑器完全兼容(它适用于条目).这个问题是已知的,并且正在进行中.

[更新2014-11-20]该问题已得到解决,并将在XF 1.3的下一个预发行版中提供

  • 如果你有里面的列表视图,这将不会很好.将滚动视图与列表视图混合会搞乱拖动事件 (4认同)

Dan*_*rts 5

有时您无法将主视图放在滚动视图中,在这种情况下,您可以通过处理iOS项目的键盘事件并将它们传递到Forms级别来实现.Android会照顾它自己.

using System;
using Foundation;
using UIKit;
using RaiseKeyboard.iOS;

[assembly: Xamarin.Forms.Dependency (typeof (KeyboardHelper))]
namespace RaiseKeyboard.iOS
{
    // Raises keyboard changed events containing the keyboard height and
    // whether the keyboard is becoming visible or not
    public class KeyboardHelper : IKeyboardHelper
    {
        public KeyboardHelper() {
            NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardNotification);
            NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardNotification);
        }

        public event EventHandler<KeyboardHelperEventArgs> KeyboardChanged;

        private void OnKeyboardNotification (NSNotification notification)
        {
            var visible = notification.Name == UIKeyboard.WillShowNotification;
            var keyboardFrame = visible
                ? UIKeyboard.FrameEndFromNotification(notification)
                : UIKeyboard.FrameBeginFromNotification(notification);
            if (KeyboardChanged != null) {
                KeyboardChanged (this, new KeyboardHelperEventArgs (visible, (float)keyboardFrame.Height));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在表单级别:

using System;
using Xamarin.Forms;

namespace RaiseKeyboard
{
    // Provides static access to keyboard events
    public static class KeyboardHelper
    {
        private static IKeyboardHelper keyboardHelper = null;

        public static void Init() {
            if (keyboardHelper == null) {
                keyboardHelper = DependencyService.Get<IKeyboardHelper>();
            }
        }

        public static event EventHandler<KeyboardHelperEventArgs> KeyboardChanged {
            add {
                Init();
                keyboardHelper.KeyboardChanged += value;
            }
            remove {
                Init ();
                keyboardHelper.KeyboardChanged -= value;
            }
        }
    }

    public interface IKeyboardHelper
    {
        event EventHandler<KeyboardHelperEventArgs> KeyboardChanged;
    }

    public class KeyboardHelperEventArgs : EventArgs 
    {
        public readonly bool Visible;
        public readonly float Height;

        public KeyboardHelperEventArgs(bool visible, float height) {
            Visible = visible;
            Height = height;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

如果您正在使用Stacklayout并希望提升键盘上方的视图,则可以在堆栈底部放置一个高度为0的垫片.然后在引发键盘更改事件时将其设置为键盘的高度.

spacer.HeightRequest = e.Visible ? e.Height : 0;
Run Code Online (Sandbox Code Playgroud)

如果您正在使用Listview,则可以通过将视图转换为重叠的数量来处理此问题.

bottomOffset = mainStack.Bounds.Bottom - textStack.Bounds.Bottom;
textStack.TranslationY -= e.Visible ? e.Height - bottomOffset : bottomOffset - e.Height;
Run Code Online (Sandbox Code Playgroud)

列表视图必须以不同方式处理,因为高度会自动通过表单进行调整,并使用间隔结果进行校正.

示例:https://github.com/naturalistic/raisekeyboard