如何获取 String of TextInput 中的当前行数?
How to get the current number of lines in String of TextInput?
在 TextInput
中输入文字后
我想知道 TextInput
中的当前行数。
要么
当前数strings
也是可以的
我试过string.split('\n').length
,但是这段代码没有检测到当文本大于屏幕时该行自动递增。
如何获取行数
当我在 Swift
中制作此功能时
使用 string.enumerateLines
函数实现。
你们有类似的功能吗?
据我所知,没有官方方法可以获取当前使用的行数,但我有一个解决方法:
我们使用 TextInput
的 onLayout
方法,并跟踪当前使用的高度。我们需要两个状态变量:
this.state = {
height: 0, // here we track the currently used height
usedLines: 0,// here we calculate the currently used lines
}
onLayout:
_onLayout(e) {
console.log('e', e.nativeEvent.layout.height);
// the height increased therefore we also increase the usedLine counter
if (this.state.height < e.nativeEvent.layout.height) {
this.setState({usedLines: this.state.usedLines+1});
}
// the height decreased, we subtract a line from the line counter
if (this.state.height > e.nativeEvent.layout.height){
this.setState({usedLines: this.state.usedLines-1});
}
// update height if necessary
if (this.state.height != e.nativeEvent.layout.height){
this.setState({height: e.nativeEvent.layout.height});
}
}
渲染方法
render() {
console.log('usedLines', this.state.usedLines);
return (
<View style={styles.container}>
<TextInput multiline style={{backgroundColor: 'green'}} onLayout={(e)=> this._onLayout(e)} />
</View>
);
}
工作示例:
对于 react-native 版本 >= 0.46.1
您可以使用 onContentSizeChange 来获得更准确的线轨迹,例如使用如下反应钩子:
/**
* used to tracker content height and current lines
*/
const [contentHeightTracker, setContentHeightTracker] = useState<{
height: number,
usedLines: number;
}>({
height: 0,
usedLines: 0
});
useEffect(() => {
// console.log('used line change : ' + lineAndHeightTracker.usedLines);
// console.log('props.extremeLines : ' + props.extremeLines);
if (contentHeightTracker.usedLines === props.extremeLines) {
if (extremeHeight.current === undefined) {
extremeHeight.current = contentHeightTracker.height;
}
}
//callback height change
if (contentHeightTracker.height !== 0) {
props.heightChange && props.heightChange(contentHeightTracker.height,
contentHeightTracker.usedLines >= props.extremeLines,
extremeHeight.current);
}
}, [contentHeightTracker]);
const _onContentHeightChange = (event: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) => {
// console.log('event height : ', event.nativeEvent.contentSize.height);
// console.log('tracker height : ', lineAndHeightTracker.height);
// the height increased therefore we also increase the usedLine counter
if (contentHeightTracker.height < event.nativeEvent.contentSize.height) {
setContentHeightTracker({
height: event.nativeEvent.contentSize.height,
usedLines: contentHeightTracker.usedLines + 1
});
} else {
// the height decreased, we subtract a line from the line counter
if (contentHeightTracker.height > event.nativeEvent.contentSize.height) {
setContentHeightTracker({
height: event.nativeEvent.contentSize.height,
usedLines: contentHeightTracker.usedLines - 1
});
}
}
};
render() {
console.log('usedLines', this.state.usedLines);
return (
<View style={styles.container}>
<TextInput
multiline
style={{backgroundColor: 'green'}}
onContentSizeChange={_onContentHeightChange}
/>
</View>
);
}
如果用户出现以下情况,其他解决方案可能会失败:
- 突出显示大量行并一次删除它们
- 一次粘贴很多行
解决此问题的一种方法是将 lineHeight
设置为 <TextInput>
并使用 onContentSizeChange
属性:
<TextInput
style={{
lineHeight: 20,
}}
onContentSizeChange={e =>
console.log(e.nativeEvent.contentSize.height / 20) // prints number of lines
}
/>
在 TextInput
中输入文字后
我想知道 TextInput
中的当前行数。
要么
当前数strings
也是可以的
我试过string.split('\n').length
,但是这段代码没有检测到当文本大于屏幕时该行自动递增。
如何获取行数
当我在 Swift
中制作此功能时
使用 string.enumerateLines
函数实现。
你们有类似的功能吗?
据我所知,没有官方方法可以获取当前使用的行数,但我有一个解决方法:
我们使用 TextInput
的 onLayout
方法,并跟踪当前使用的高度。我们需要两个状态变量:
this.state = {
height: 0, // here we track the currently used height
usedLines: 0,// here we calculate the currently used lines
}
onLayout:
_onLayout(e) {
console.log('e', e.nativeEvent.layout.height);
// the height increased therefore we also increase the usedLine counter
if (this.state.height < e.nativeEvent.layout.height) {
this.setState({usedLines: this.state.usedLines+1});
}
// the height decreased, we subtract a line from the line counter
if (this.state.height > e.nativeEvent.layout.height){
this.setState({usedLines: this.state.usedLines-1});
}
// update height if necessary
if (this.state.height != e.nativeEvent.layout.height){
this.setState({height: e.nativeEvent.layout.height});
}
}
渲染方法
render() {
console.log('usedLines', this.state.usedLines);
return (
<View style={styles.container}>
<TextInput multiline style={{backgroundColor: 'green'}} onLayout={(e)=> this._onLayout(e)} />
</View>
);
}
工作示例:
对于 react-native 版本 >= 0.46.1
您可以使用 onContentSizeChange 来获得更准确的线轨迹,例如使用如下反应钩子:
/**
* used to tracker content height and current lines
*/
const [contentHeightTracker, setContentHeightTracker] = useState<{
height: number,
usedLines: number;
}>({
height: 0,
usedLines: 0
});
useEffect(() => {
// console.log('used line change : ' + lineAndHeightTracker.usedLines);
// console.log('props.extremeLines : ' + props.extremeLines);
if (contentHeightTracker.usedLines === props.extremeLines) {
if (extremeHeight.current === undefined) {
extremeHeight.current = contentHeightTracker.height;
}
}
//callback height change
if (contentHeightTracker.height !== 0) {
props.heightChange && props.heightChange(contentHeightTracker.height,
contentHeightTracker.usedLines >= props.extremeLines,
extremeHeight.current);
}
}, [contentHeightTracker]);
const _onContentHeightChange = (event: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) => {
// console.log('event height : ', event.nativeEvent.contentSize.height);
// console.log('tracker height : ', lineAndHeightTracker.height);
// the height increased therefore we also increase the usedLine counter
if (contentHeightTracker.height < event.nativeEvent.contentSize.height) {
setContentHeightTracker({
height: event.nativeEvent.contentSize.height,
usedLines: contentHeightTracker.usedLines + 1
});
} else {
// the height decreased, we subtract a line from the line counter
if (contentHeightTracker.height > event.nativeEvent.contentSize.height) {
setContentHeightTracker({
height: event.nativeEvent.contentSize.height,
usedLines: contentHeightTracker.usedLines - 1
});
}
}
};
render() {
console.log('usedLines', this.state.usedLines);
return (
<View style={styles.container}>
<TextInput
multiline
style={{backgroundColor: 'green'}}
onContentSizeChange={_onContentHeightChange}
/>
</View>
);
}
如果用户出现以下情况,其他解决方案可能会失败:
- 突出显示大量行并一次删除它们
- 一次粘贴很多行
解决此问题的一种方法是将 lineHeight
设置为 <TextInput>
并使用 onContentSizeChange
属性:
<TextInput
style={{
lineHeight: 20,
}}
onContentSizeChange={e =>
console.log(e.nativeEvent.contentSize.height / 20) // prints number of lines
}
/>