[英]React Native - adjust scrollview as keyboard shows up (ios)
在我的聊天应用程序中,当键盘从视图底部显示时,我无法为scrollview(聊天视图)设置动画以向上滑动/调整。
如果您使用过Messengers,WeChat,Line等任何主要的聊天应用程序,您都会看到随着键盘的显示,您的聊天屏幕如何平稳地上升。 现在,我模仿了KeyboardAvoidingView并实现了类似的东西:
// Triggered by Keyboard.addListener("keyboardWillChangeFrame", onKeyboardChange);
const onKeyboardChange = e => {
if (!e) {
//this is scroll view's contentInset.top
setSpacing(0);
return;
}
const { duration, easing, endCoordinates, startCoordinates } = e;
let offset;
if (startCoordinates) {
offset = startCoordinates.screenY - endCoordinates.screenY;
} else {
offset = endCoordinates.height;
}
const spacing = offset > 0 ? offset : 0;
if (duration && easing) {
LayoutAnimation.configureNext({
// We have to pass the duration equal to minimal accepted duration defined here: RCTLayoutAnimation.m
duration: duration > 10 ? duration : 10,
update: {
duration: duration > 10 ? duration : 10,
type: LayoutAnimation.Types[easing] || "keyboard"
}
});
}
//this is scroll view's contentInset.top
setSpacing(spacing);
};
如您所见,我当前仅使用KeyboardWillChangeFrame传递的事件并使用LayoutAnimation来动画向上滚动scrollview来计算偏移量。 它工作得很好,但我仍然可以看到一点延迟。
在本机iOS开发中,可以使用animateKeyframes来实现:
@objc func keyboardWillShow(notification: NSNotification){
let duration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt
let curFrame = (notification.userInfo![UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.origin.y - curFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.view.frame.origin.y += deltaY
})
}
但似乎它在React Native中不可用。 无论如何,当键盘从底部尽可能平滑地显示时,我可以调整滚动视图吗?
你必须做两件事
1:首先使用react-native-keyboard-spacer使Textinput容器滚动
2:显示/隐藏键盘时设置ChatList的偏移量
完整的代码
import React from "react";
import { View, FlatList, Text, TextInput, Keyboard } from "react-native";
import KeyboardSpacer from "react-native-keyboard-spacer";
export default class App extends React.Component {
state = {
chat: [
{ id: 1, text: "Test1 1" },
{ id: 2, text: "Test1 2" },
{ id: 3, text: "Test1 3" },
{ id: 4, text: "Test1 4" },
{ id: 5, text: "Test1 5" },
{ id: 6, text: "Test1 6" },
{ id: 7, text: "Test1 7" },
{ id: 8, text: "Test1 8" },
{ id: 9, text: "Test1 9" },
{ id: 10, text: "Test1 10" },
{ id: 11, text: "Test1 11" },
{ id: 12, text: "Test1 12" },
{ id: 13, text: "Test1 13" },
{ id: 14, text: "Test1 14" },
{ id: 15, text: "Test1 15" },
{ id: 16, text: "Test1 16" },
{ id: 17, text: "Test1 17" },
{ id: 18, text: "Test1 18" },
{ id: 19, text: "Test1 19" },
{ id: 20, text: "Test1 20" },
{ id: 21, text: "Test1 21" },
{ id: 22, text: "Test1 22" },
{ id: 23, text: "Test1 23" },
{ id: 24, text: "Test1 24" }
]
};
scrollOffset = 0;
keyboardHeight = 0;
componentDidMount() {
this.keyboardWillShowListener = Keyboard.addListener(
"keyboardWillShow",
this._keyboardWillShow
);
this.keyboardWillHideListener = Keyboard.addListener(
"keyboardWillHide",
this._keyboardWillHide
);
}
componentWillUnmount() {
this.keyboardWillShowListener.remove();
this.keyboardWillHideListener.remove();
}
_keyboardWillShow = e => {
this.keyboardHeight = e.endCoordinates
? e.endCoordinates.height
: e.end.height;
const newOffset = this.scrollOffset + this.keyboardHeight;
this.chatList.scrollToOffset({ offset: newOffset, animated: true });
};
_keyboardWillHide = e => {
const newOffset = this.scrollOffset - this.keyboardHeight;
this.chatList.scrollToOffset({ offset: newOffset, animated: true });
};
handleScroll = e => {
this.scrollOffset = e.nativeEvent.contentOffset.y;
};
render() {
return (
<View style={{ flex: 1, marginTop: 30 }}>
<FlatList
style={{ flex: 1 }}
ref={ref => {
this.chatList = ref;
}}
data={this.state.chat}
renderItem={({ item }) => (
<Text style={{ padding: 20 }}>{item.text}</Text>
)}
onScroll={this.handleScroll}
/>
<TextInput
placeholder="Enter Message"
style={{ padding: 20, borderTopWidth: 1, borderColor: "black" }}
/>
<KeyboardSpacer />
</View>
);
}
}
应用预览
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.