React Native如何获取TextInput当前光标位置并实现输入#弹出选项?
React Native TextInput 光标位置获取及#号触发候选框实现方案
可以直接通过TextInput官方提供的属性和回调实现需求,完整实现步骤如下:
1. 获取光标位置
TextInput 自带 onSelectionChange 回调,会返回当前光标/选中文本的范围,无选中内容时返回的start值就是当前光标的下标:
import { useState, useRef } from 'react'; import { TextInput } from 'react-native'; const Demo = () => { const [inputValue, setInputValue] = useState(''); // 存储光标位置,start和end相同时就是光标所在位置 const [selection, setSelection] = useState({ start: 0, end: 0 }); const inputRef = useRef(null); return ( <TextInput ref={inputRef} value={inputValue} onChangeText={setInputValue} onSelectionChange={(e) => { setSelection(e.nativeEvent.selection); }} style={{ fontSize: 16, lineHeight: 22, padding: 10, borderWidth: 1, borderColor: '#eee' }} /> ) }
2. 监听#号输入触发候选框
在文本变更回调中判断是否输入了#号,触发候选框展示逻辑:
const [showCandidateMenu, setShowCandidateMenu] = useState(false); const handleTextChange = (text) => { setInputValue(text); // 判断最新输入的字符为#号 if (text.slice(-1) === '#') { setShowCandidateMenu(true); // 调用方法计算候选框位置 calculateMenuPosition(); } else { setShowCandidateMenu(false); } }
3. 计算候选框展示坐标
要实现候选框显示在光标上方,需要结合输入框的绝对坐标和光标位置计算定位坐标:
const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 }); const calculateMenuPosition = () => { inputRef.current?.measure((x, y, width, height, pageX, pageY) => { // 按你的字体大小调整单个字符宽度、行高参数 const singleCharWidth = 10; const lineHeight = 22; const maxCharPerLine = 30; // 计算光标相对于输入框左上角的偏移 const cursorOffsetX = selection.start * singleCharWidth; const cursorOffsetY = Math.floor(selection.start / maxCharPerLine) * lineHeight; // 计算候选框的绝对坐标,调整数值适配你的UI setMenuPosition({ top: pageY + cursorOffsetY - 50, // 50为候选框高度,向上偏移展示在光标上方 left: pageX + cursorOffsetX }) }) }
4. 渲染候选列表
用绝对定位的视图渲染候选列表即可,实现效果如下:
内容的提问来源于stack exchange,提问作者Hamas Hassan
相关产品推荐
相关产品推荐

