Browse Source

improved updating size on ios

iou90 6 years ago
parent
commit
5dac43b2c4
3 changed files with 64 additions and 64 deletions
  1. 11
    28
      autoHeightWebView/common.js
  2. 52
    35
      autoHeightWebView/index.ios.js
  3. 1
    1
      demo/App.js

+ 11
- 28
autoHeightWebView/common.js View File

@@ -97,26 +97,19 @@ export function isEqual(newProps, oldProps) {
97 97
   return isChanged(getReloadRelatedData(newProps), getReloadRelatedData(oldProps));
98 98
 }
99 99
 
100
-export function setState(props, getBaseScript, getIframeBaseScript) {
101
-  const { source, style } = props;
100
+export function setState(props, baseUrl, getBaseScript, getIframeBaseScript) {
101
+  const { source } = props;
102 102
   const script = getScript(props, getBaseScript, getIframeBaseScript);
103
-  let state = {
104
-    height: style && style.height ? style.height : 0,
105
-    width: getWidth(style)
106
-  };
103
+  let state = {};
107 104
   if (source.html) {
108
-    Object.assign(state, {
109
-      source: Object.assign(
110
-        {},
111
-        {
112
-          html: getInjectedSource(source.html, script),
113
-          baseUrl: 'web/'
114
-        }
115
-      )
116
-    });
105
+    let currentSource = { html: getInjectedSource(source.html, script) };
106
+    baseUrl && Object.assign(currentSource, { baseUrl });
107
+    Object.assign(state, { source: currentSource });
117 108
   } else {
109
+    let currentSource = Object.assign({}, source);
110
+    baseUrl && Object.assign(currentSource, { baseUrl });
118 111
     Object.assign(state, {
119
-      source: Object.assign({}, source, { baseUrl: 'web/' }),
112
+      source: currentSource,
120 113
       script
121 114
     });
122 115
   }
@@ -131,17 +124,8 @@ export function handleSizeUpdated(height, width, onSizeUpdated) {
131 124
     });
132 125
 }
133 126
 
134
-export function getSize(newHeight, newWidth, height, width, updatingSize, calledOnce) {
135
-  if (!calledOnce || updatingSize) {
136
-    return {
137
-      h: height,
138
-      w: width
139
-    };
140
-  }
141
-  return {
142
-    h: height,
143
-    w: width
144
-  };
127
+export function isSizeChanged(height, oldHeight, width, oldWidth) {
128
+  return (height && height !== oldHeight) || (width && width !== oldWidth);
145 129
 }
146 130
 
147 131
 export const domMutationObserveScript = `
@@ -163,4 +147,3 @@ function getSize(container) {
163 147
   };
164 148
 }
165 149
 `;
166
-

+ 52
- 35
autoHeightWebView/index.ios.js View File

@@ -6,7 +6,15 @@ import { Animated, StyleSheet, ViewPropTypes, WebView } from 'react-native';
6 6
 
7 7
 import PropTypes from 'prop-types';
8 8
 
9
-import { getSize, isEqual, setState, getWidth, handleSizeUpdated, domMutationObserveScript, getCurrentSize } from './common.js';
9
+import {
10
+  isEqual,
11
+  setState,
12
+  getWidth,
13
+  isSizeChanged,
14
+  handleSizeUpdated,
15
+  domMutationObserveScript,
16
+  getCurrentSize
17
+} from './common.js';
10 18
 
11 19
 import momoize from './momoize';
12 20
 
@@ -57,6 +65,7 @@ export default class AutoHeightWebView extends PureComponent {
57 65
     enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
58 66
     this.webView = React.createRef();
59 67
     this.state = {
68
+      isSizeChanged: false,
60 69
       width: getWidth(style),
61 70
       height: style && style.height ? style.height : 0
62 71
     };
@@ -64,6 +73,38 @@ export default class AutoHeightWebView extends PureComponent {
64 73
 
65 74
   getUpdatedState = momoize(setState, isEqual);
66 75
 
76
+  static getDerivedStateFromProps(props, state) {
77
+    const { height: oldHeight, width: oldWidth } = state;
78
+    const height = props.style ? props.style.height : null;
79
+    const width = props.style ? props.style.width : null;
80
+    if (isSizeChanged(height, oldHeight, width, oldWidth)) {
81
+      return {
82
+        height,
83
+        width,
84
+        isSizeChanged: true
85
+      };
86
+    }
87
+    return null;
88
+  }
89
+
90
+  componentDidUpdate() {
91
+    const { height, width, isSizeChanged } = this.state;
92
+    if (isSizeChanged) {
93
+      const { enableAnimation, animationDuration, onSizeUpdated } = this.props;
94
+      if (enableAnimation) {
95
+        Animated.timing(this.opacityAnimatedValue, {
96
+          toValue: 1,
97
+          duration: animationDuration
98
+        }).start(() => {
99
+          handleSizeUpdated(height, width, onSizeUpdated);
100
+        });
101
+      } else {
102
+        handleSizeUpdated(height, width, onSizeUpdated);
103
+      }
104
+      this.setState({ isSizeChanged: false });
105
+    }
106
+  }
107
+
67 108
   handleNavigationStateChange = navState => {
68 109
     const { title } = navState;
69 110
     if (!title) {
@@ -73,30 +114,13 @@ export default class AutoHeightWebView extends PureComponent {
73 114
     const width = Number(widthValue);
74 115
     const height = Number(heightValue);
75 116
     const { height: oldHeight, width: oldWidth } = this.state;
76
-    if ((height && height !== oldHeight) || (width && width !== oldWidth)) {
77
-      const { enableAnimation, animationDuration, onSizeUpdated } = this.props;
78
-      enableAnimation && this.opacityAnimatedValue.setValue(0);
79
-      this.updatingSize = true;
80
-      this.setState(
81
-        {
82
-          height,
83
-          width
84
-        },
85
-        () => {
86
-          if (enableAnimation) {
87
-            Animated.timing(this.opacityAnimatedValue, {
88
-              toValue: 1,
89
-              duration: animationDuration
90
-            }).start(() => {
91
-              handleSizeUpdated(height, width, onSizeUpdated);
92
-              this.updatingSize = false;
93
-            });
94
-          } else {
95
-            handleSizeUpdated(height, width, onSizeUpdated);
96
-            this.updatingSize = false;
97
-          }
98
-        }
99
-      );
117
+    if (isSizeChanged(height, oldHeight, width, oldWidth)) {
118
+      this.props.enableAnimation && this.opacityAnimatedValue.setValue(0);
119
+      this.setState({
120
+        isSizeChanged: true,
121
+        height,
122
+        width
123
+      });
100 124
     }
101 125
   };
102 126
 
@@ -119,21 +143,15 @@ export default class AutoHeightWebView extends PureComponent {
119 143
       style,
120 144
       scrollEnabled
121 145
     } = this.props;
122
-    const { height: newHeight, width: newWidth, source, script } = this.getUpdatedState(
123
-      this.props,
124
-      getBaseScript,
125
-      getIframeBaseScript
126
-    );
127
-    const { w, h } = getSize(newHeight, newWidth, height, width, this.updatingSize, this.calledOnce);
128
-    this.calledOnce = true;
146
+    const { source, script } = this.getUpdatedState(this.props, 'web/', getBaseScript, getIframeBaseScript);
129 147
     return (
130 148
       <Animated.View
131 149
         style={[
132 150
           styles.container,
133 151
           {
134 152
             opacity: enableAnimation ? this.opacityAnimatedValue : 1,
135
-            width: w,
136
-            height: h + heightOffset
153
+            width,
154
+            height: height + heightOffset
137 155
           },
138 156
           style
139 157
         ]}
@@ -175,7 +193,6 @@ const commonScript = `
175 193
     window.addEventListener('resize', updateSize);
176 194
     `;
177 195
 
178
-
179 196
 function getBaseScript(style) {
180 197
   return `
181 198
     ;

+ 1
- 1
demo/App.js View File

@@ -125,7 +125,7 @@ export default class Explorer extends Component {
125 125
           <Text>change style</Text>
126 126
         </TouchableOpacity>
127 127
         <TouchableOpacity onPress={this.changeScript} style={[styles.button, { marginBottom: 100 }]}>
128
-          <Text>change heightScript</Text>
128
+          <Text>change script</Text>
129 129
         </TouchableOpacity>
130 130
       </ScrollView>
131 131
     );