Xamarin.Forms中设置Editor控件光标至用户点击位置
实现Xamarin.Forms Editor光标精准定位到点击位置
需求:在Xamarin.Forms项目中实现Editor控件光标精准定位到用户点击的位置,重点适配iOS端,同时兼容Android端。由于需要多行输入,必须使用Editor而非Entry(Entry自带CursorPosition属性但不支持多行)。现有自定义渲染器会将光标固定在起始位置,需优化。
iOS端自定义渲染器优化
替换原有OnElementPropertyChanged中的硬编码逻辑,改为监听触摸事件获取点击位置并设置光标:
using Foundation; using UIKit; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; [assembly: ExportRenderer(typeof(CustomEditor), typeof(CustomEditorRenderer))] namespace YourNamespace.iOS.Renderers { public class CustomEditorRenderer : EditorRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Editor> e) { base.OnElementChanged(e); if (Control != null) { Control.TouchDown += Control_TouchDown; } } private void Control_TouchDown(object sender, EventArgs e) { if (Control == null) return; var touchLocation = Control.LocationsOfTouches(null).FirstOrDefault(); if (touchLocation == null) return; var textPosition = Control.GetPosition(Control.BeginningOfDocument, touchLocation.Value); if (textPosition != null) { Control.SelectedTextRange = Control.GetTextRange(textPosition, textPosition); } } protected override void Dispose(bool disposing) { if (disposing && Control != null) { Control.TouchDown -= Control_TouchDown; } base.Dispose(disposing); } } }
逻辑说明
- 监听Editor对应的iOS原生
UITextView的TouchDown事件,获取用户触摸坐标 - 通过
GetPosition方法将触摸坐标转换为文本位置偏移量 - 设置
SelectedTextRange为该位置,实现光标精准定位
Android端适配
通过监听触摸事件计算点击位置对应的文本偏移量,设置光标:
using Android.Content; using Android.Text; using Android.Views; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(CustomEditor), typeof(CustomEditorRenderer))] namespace YourNamespace.Droid.Renderers { public class CustomEditorRenderer : EditorRenderer { public CustomEditorRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<Editor> e) { base.OnElementChanged(e); if (Control != null) { Control.Touch += Control_Touch; } } private void Control_Touch(object sender, TouchEventArgs e) { if (e.Event.Action != MotionEventActions.Down || Control == null) return; var touchX = e.Event.GetX(); var touchY = e.Event.GetY(); var layout = Control.Layout; var line = layout.GetLineForVertical((int)touchY); var offset = layout.GetOffsetForHorizontal(line, touchX); Control.SetSelection(offset); e.Handled = false; } protected override void Dispose(bool disposing) { if (disposing && Control != null) { Control.Touch -= Control_Touch; } base.Dispose(disposing); } } }
逻辑说明
- 监听Android原生
EditText的Touch事件,获取触摸坐标 - 通过
Layout对象计算触摸位置对应的文本行和偏移量 - 调用
SetSelection设置光标到对应位置,保留默认事件处理确保正常聚焦
共享项目自定义控件
保持原有自定义Editor即可,无需额外属性:
namespace YourNamespace.Controls { public class CustomEditor : Editor { } }
内容的提问来源于stack exchange,提问作者RMR
相关产品推荐
相关产品推荐

