繁体   English   中英

React Native-在键盘显示时调整滚动视图(iOS)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM