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

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);
        }
    }
}

逻辑说明

  1. 监听Editor对应的iOS原生UITextView的TouchDown事件,获取用户触摸坐标
  2. 通过GetPosition方法将触摸坐标转换为文本位置偏移量
  3. 设置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);
        }
    }
}

逻辑说明

  1. 监听Android原生EditText的Touch事件,获取触摸坐标
  2. 通过Layout对象计算触摸位置对应的文本行和偏移量
  3. 调用SetSelection设置光标到对应位置,保留默认事件处理确保正常聚焦

共享项目自定义控件

保持原有自定义Editor即可,无需额外属性:

namespace YourNamespace.Controls
{
    public class CustomEditor : Editor
    {
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:10:29