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

