完整代码
import React, { forwardRef, Ref, useImperativeHandle, useState } from "react";
import {
Modal,
StyleSheet,
Text,
View, TouchableOpacity, TextInput, ScrollView, Dimensions
} from "react-native";
let width: number = Dimensions.get('window').width;
let w: number = width / 480; //效果是基于480设计的
export type RemarkRef = {
//通过ref调用 val:默认值 callback:回调方法
show: (val?: string, callback?: Function) => void
}
export type RemarkProps = {
maxLength?: number, //备注最大长度
placeholder?: string
}
const Remark = (props: RemarkProps, ref: Ref<RemarkRef>) => {
let { maxLength = 255, placeholder } = props;
const [modalVisible, setModalVisible] = useState(false);
const [value, onChangeText] = useState('');
const [cBack, setCBack] = useState<Function>(() => { });
useImperativeHandle(ref, () => ({
show(val?: string, callback?: Function) {
onChangeText(val || "");
if (callback) {
//此处赋值需注意 如果直接 setCBack(callback) 下面拿到的cBack为空
setCBack(() => callback)
}
setModalVisible(true);
}
}))
const save = () => {
if (cBack) {
cBack(value);
}
setModalVisible(false);
}
return (
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.contentView}>
<View style={styles.header}>
<TouchableOpacity activeOpacity={1} onPress={() => {
setModalVisible(false);
}}>
<Text style={styles.hTxt}>取消</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={1} onPress={save}>
<Text style={styles.hTxt}>保存</Text>
</TouchableOpacity>
</View>
<Text style={styles.rtip}>备注</Text>
<View style={styles.line}></View>
<ScrollView style={styles.scrollView}>
<View style={styles.inputView}>
<TextInput
placeholder={placeholder || "请输入备注"}
multiline={true}
style={styles.rinput}
maxLength={maxLength}
onChangeText={text => onChangeText(text)}
value={value}
defaultValue={value}
/>
<Text style={styles.tip}>{value.length + "/" + maxLength}</Text>
</View>
</ScrollView>
</View>
</View>
</Modal >
);
};
const styles = StyleSheet.create({
centeredView: {
flex: 1,
justifyContent: 'flex-end',
backgroundColor: 'rgba(149, 157, 165, 0.5)',
},
contentView: {
height: 548 * w,
maxHeight: 548 * w,
flex: 1,
backgroundColor: 'white',
borderTopLeftRadius: 30 * w,
borderTopRightRadius: 30 * w,
overflow: "hidden",
paddingBottom: 20 * w
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 25 * w,
paddingHorizontal: 32 * w
},
hTxt: {
fontSize: 22,
color: '#1592A3'
},
rtip: {
marginLeft: 32 * w,
marginTop: 19 * w,
fontSize: 25 * w
},
line: {
height: StyleSheet.hairlineWidth,
backgroundColor: '#EEEEEE',
marginVertical: 16 * w
},
scrollView: {
backgroundColor: '#F9F9F9'
},
inputView: {
flex: 1,
},
rinput: {
paddingHorizontal: 32 * w,
paddingVertical: 16 * w,
backgroundColor: 'white'
},
tip: {
backgroundColor: 'white',
color: '#999999',
paddingHorizontal: 32 * w,
paddingBottom: 20 * w,
textAlign: 'right'
}
});
export default forwardRef(Remark);
注意事项:
为防止整个modal页面顶到手机外面, 需要用ScrollView包裹需要滚动的View。