react-native ios 应用程序在设备旋转时不会重新呈现

react-native ios app doesn't rerender when device is rotated

当我旋转设备时,旧视图会旋转但保持原来的尺寸,只是使用屏幕的一部分,直到屏幕被触摸,然后它会重新呈现。 (这是在发布模式下:在调试模式下,它会自动重新渲染,但只会在一两秒的延迟之后)。这发生在模拟器和设备 运行 iOS7 和 iOS9.

我将我的应用程序从 react-native 0.24.1 升级到 0.32.0 后出现了这个问题。当然,这种升级就像从毛衣中抽出线一样,使得有必要升级许多第 3 方 react-native 库。特别是,将 react-native-router-flux 从 3.24.1 升级到 3.35.0 需要对我的代码进行大量更改。

就是说,我想不出我所做的任何更改可能会导致此问题。起初我怀疑 react-native-orientation 升级特别棘手,所以我只是将它从项目中完全删除,这没有帮助。

我在我的顶层视图中添加了 onLayout 事件的回调,带有 console.log 打印输出。设备旋转后显然不会触发此事件,直到触摸屏幕。然后打印 onLayout 调试语句,同时 react-native 代码重新渲染。

因此,本机代码似乎不会通过桥将旋转事件发送到 javascript 代码,直到它可以搭载其他事件。

如有任何关于如何调试的建议,我们将不胜感激。

更新:我只记得关于 flex:1 0.28 中的重大更改的说明。我想知道这是否与它有关?他们说:

If you previously used flex: 1 where not necessary this change will likely break your layout

问题是,什么时候需要,怎么知道有没有必要?我似乎找不到关于它的文档。我总是在任何地方都使用 flex:1,因为我发现如果不这样做,就会发生不好的事情。在 Scrollview 文档中说:

Forgetting to transfer {flex: 1} down the view stack can lead to errors here

现在看来,如果你这样做,坏事就会发生。无赖。看来他们真的想让你知道你在做什么。黑客要做什么?

更新 2:这似乎不是问题所在。黑客所做的当然是黑客行为。我从顶层开始逐一删除每个 {flex: 1}。在大多数情况下,它破坏了布局,而且在任何情况下都没有解决这个问题。

这显然是 react-native 0.32.0 中的错误。

我决定清理所有内容并从 npm 重新安装:

rm -rf $TMPDIR/react-* && watchman watch-del-all && rm -rf ios/build/ModuleCache/* && rm -rf node_modules/ && npm cache clean && npm i

当我这样做时,它启动了 react-native 0.32.1,问题就消失了。 0.32.1 有一个 commit 似乎与此有关。

它在 RN 0.44.0 中仍然不起作用,我在每个渲染中检查屏幕宽度并相应地调整子项的大小,但是 render 不会在设备旋转时调用。只有当我按下 Cmd-D 刷新时,所有内容才会正确重新呈现。

render() {
   let { width } = Dimensions.get('window');
   ...
}

要在旋转后重新渲染,请尝试将其放入视图的构造函数 () 中:

Dimensions.addEventListener('change', () => {
  this.setState({});
});