You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms聊天页面:键盘弹出时附件与发送图标消失问题

问题:键盘弹出时附件与发送图标未随Editor上移

我用CustomEditorRenderer解决了键盘与Editor的间距问题,之前已在Stack Overflow提交工单。当前聊天页面的附件、发送图标和Editor处于同一布局,但键盘弹出时只有Editor显示,图标直接消失了。以下是我的XAML布局代码和iOS端CustomEditorRenderer实现代码,请问怎么让附件和发送图标跟着键盘一起上移?

UI截图:
UI截图

XAML代码:

<Grid 
x:Name="newcomment_stack"
Margin="2,0,2,10"
IsVisible="false">

<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="8*" />
    <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<Image 
Grid.Row="0" 
Grid.Column="0"
VerticalOptions="CenterAndExpand"
x:Name="Attachment_Image"
Source="ic_attachment_xx.png">
    <Image.WidthRequest>
        <OnIdiom x:TypeArguments="x:Double">
            <OnIdiom.Phone>40</OnIdiom.Phone>
            <OnIdiom.Tablet>60</OnIdiom.Tablet>
            <OnIdiom.Desktop>40</OnIdiom.Desktop>
        </OnIdiom>
    </Image.WidthRequest>
    <Image.HeightRequest>
        <OnIdiom x:TypeArguments="x:Double">
            <OnIdiom.Phone>40</OnIdiom.Phone>
            <OnIdiom.Tablet>60</OnIdiom.Tablet>
            <OnIdiom.Desktop>40</OnIdiom.Desktop>
        </OnIdiom>
    </Image.HeightRequest>
</Image>

<renderer:CustomEditor
    Grid.Row="0" 
    Grid.Column="1"
    x:Name="commentbody_entry"
    Placeholder="Add your comment here"
    BackgroundColor="#f1f1f1"
    PlaceholderColor = "#a39ea1"
    TextColor = "#54493b"
    TextChanged="commentbody_entry_TextChanged"
    Style="{StaticResource AddCommentEditorStyle}">
    <renderer:CustomEditor.HeightRequest>
        <OnIdiom x:TypeArguments="x:Double">
            <OnIdiom.Phone>60</OnIdiom.Phone>
            <OnIdiom.Tablet>90</OnIdiom.Tablet>
            <OnIdiom.Desktop>60</OnIdiom.Desktop>
        </OnIdiom>
    </renderer:CustomEditor.HeightRequest>
</renderer:CustomEditor>

<StackLayout 
    x:Name="sendcomment_stack"
    IsEnabled="False"
    VerticalOptions="CenterAndExpand"
    Grid.Row="0" 
    Grid.Column="2">
    <Image 
        x:Name="sendcomment_image"
        Source="ic_gray_sendcomment_xx.png">
        <Image.WidthRequest>
            <OnIdiom x:TypeArguments="x:Double">
                <OnIdiom.Phone>40</OnIdiom.Phone>
                <OnIdiom.Tablet>60</OnIdiom.Tablet>
                <OnIdiom.Desktop>40</OnIdiom.Desktop>
            </OnIdiom>
        </Image.WidthRequest>
        <Image.HeightRequest>
            <OnIdiom x:TypeArguments="x:Double">
                <OnIdiom.Phone>40</OnIdiom.Phone>
                <OnIdiom.Tablet>60</OnIdiom.Tablet>
                <OnIdiom.Desktop>40</OnIdiom.Desktop>
            </OnIdiom>
        </Image.HeightRequest>
    </Image>
    <StackLayout.GestureRecognizers>
        <TapGestureRecognizer
            Tapped="Send_Comment"
            NumberOfTapsRequired="1">
        </TapGestureRecognizer>
    </StackLayout.GestureRecognizers>
</StackLayout>
</Grid>

iOS端CustomEditorRenderer代码:

public class CustomEditorRenderer : EditorRenderer
{
    public CustomEditorRenderer()
    {
        UIKeyboard.Notifications.ObserveWillShow((sender, args) =>
        {
            if (Element != null)
            {
                Element.Margin = new Thickness(0, 0, 0, args.FrameEnd.Height); //push the entry up to keyboard height when keyboard is activated
            }
        });

        UIKeyboard.Notifications.ObserveWillHide((sender, args) =>
        {
            if (Element != null)
            {
                Element.Margin = new Thickness(0); //set the margins to zero when keyboard is dismissed
            }
        });
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
    {
        base.OnElementChanged(e);

        if (Control != null)
        {
            Control.Layer.CornerRadius = 10;
            Control.TextColor = UIColor.Black;
        }
    }
}

解决方案

问题出在你只修改了Editor的Margin,而附件和发送图标是外层Grid的子元素,单独调整Editor会导致布局挤压,图标被挤出可视区域。正确的做法是控制整个外层Grid的位置,让所有元素一起上移:

步骤1:移除EditorRenderer里的键盘监听

修改你的CustomEditorRenderer,删掉构造函数里的键盘监听代码,只保留样式相关逻辑:

public class CustomEditorRenderer : EditorRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
    {
        base.OnElementChanged(e);

        if (Control != null)
        {
            Control.Layer.CornerRadius = 10;
            Control.TextColor = UIColor.Black;
        }
    }
}

步骤2:在页面后台处理键盘通知

打开包含这个Grid的页面代码文件,添加键盘显示/隐藏的监听,直接修改外层newcomment_stack的Margin:

using Foundation;
using UIKit;
// 其他必要的命名空间

public partial class YourChatPage : ContentPage
{
    public YourChatPage()
    {
        InitializeComponent();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        // 注册键盘通知
        UIKeyboard.Notifications.ObserveWillShow(OnKeyboardWillShow);
        UIKeyboard.Notifications.ObserveWillHide(OnKeyboardWillHide);
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        // 移除通知监听,避免内存泄漏
        UIKeyboard.Notifications.RemoveObserver(OnKeyboardWillShow);
        UIKeyboard.Notifications.RemoveObserver(OnKeyboardWillHide);
    }

    private void OnKeyboardWillShow(object sender, UIKeyboardEventArgs args)
    {
        if (newcomment_stack != null)
        {
            // 保留原来的左右上Margin,底部Margin改为原10加上键盘高度
            newcomment_stack.Margin = new Thickness(2, 0, 2, args.FrameEnd.Height + 10);
        }
    }

    private void OnKeyboardWillHide(object sender, UIKeyboardEventArgs args)
    {
        if (newcomment_stack != null)
        {
            // 恢复原来的Margin值
            newcomment_stack.Margin = new Thickness(2, 0, 2, 10);
        }
    }
}

这样整个包含Editor、附件、发送图标的Grid会整体上移,所有元素都能保持在同一布局中显示,不会出现图标消失的问题。


内容的提问来源于stack exchange,提问作者Sreejith Sree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:59:56