@mpxjs/webpack-plugin 2.9.69-beta.1 → 2.9.69-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import Reanimated, { Extrapolation, interpolate, useAnimatedStyle, useSharedValu
3
3
  import { wrapChildren, extendObject } from './utils';
4
4
  import { createFaces } from './pickerFaces';
5
5
  import { usePickerViewColumnAnimationContext } from './pickerVIewContext';
6
- const _PickerViewColumnItem = ({ item, index, itemHeight, itemWidth, textStyleFromParent, textStyle, hasVarDec, varContext, textProps, visibleCount, onItemLayout }) => {
6
+ const _PickerViewColumnItem = ({ item, index, itemHeight, itemWidth = '100%', textStyleFromParent, textStyle, hasVarDec, varContext, textProps, visibleCount, onItemLayout }) => {
7
7
  const offsetYShared = usePickerViewColumnAnimationContext();
8
8
  const facesShared = useSharedValue(createFaces(itemHeight, visibleCount));
9
9
  useEffect(() => {
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react';
2
2
  import { SafeAreaView, StyleSheet } from 'react-native';
3
3
  import Reanimated, { useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated';
4
- import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid } from './utils';
4
+ import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, useDebounceCallback, useStableCallback, isIOS } from './utils';
5
5
  import useNodesRef from './useNodesRef';
6
6
  import PickerOverlay from './pickerViewOverlay';
7
7
  import PickerMask from './pickerViewMask';
@@ -20,11 +20,8 @@ const _PickerViewColumn = forwardRef((props, ref) => {
20
20
  style: normalStyle
21
21
  });
22
22
  const { height: pickerH, itemHeight } = wrapperStyle;
23
- const [scrollViewWidth, setScrollViewWidth] = useState('100%');
24
- const [itemRawW, setItemRawW] = useState('100%');
25
23
  const [itemRawH, setItemRawH] = useState(itemHeight);
26
24
  const maxIndex = useMemo(() => columnData.length - 1, [columnData]);
27
- const maxScrollViewWidth = useRef(-1);
28
25
  const prevScrollingInfo = useRef({ index: initialIndex, y: 0 });
29
26
  const touching = useRef(false);
30
27
  const scrolling = useRef(false);
@@ -39,10 +36,6 @@ const _PickerViewColumn = forwardRef((props, ref) => {
39
36
  nodeRef: scrollViewRef
40
37
  });
41
38
  // console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length, 'pickerH=', pickerH, 'itemRawH=', itemRawH, 'itemHeight=', itemHeight)
42
- // const initialOffset = useMemo(() => ({
43
- // x: 0,
44
- // y: itemRawH * initialIndex
45
- // }), [itemRawH])
46
39
  const paddingHeight = useMemo(() => Math.round((pickerH - itemHeight) / 2), [pickerH, itemHeight]);
47
40
  const snapToOffsets = useMemo(() => columnData.map((_, i) => i * itemRawH), [columnData, itemRawH]);
48
41
  const contentContainerStyle = useMemo(() => {
@@ -52,8 +45,27 @@ const _PickerViewColumn = forwardRef((props, ref) => {
52
45
  const calc = Math.round(y / itemRawH);
53
46
  return Math.max(0, Math.min(calc, maxIndex));
54
47
  }, [itemRawH, maxIndex]);
48
+ const getYofIndex = useCallback((index) => {
49
+ return index * itemRawH;
50
+ }, [itemRawH]);
51
+ const stableResetScrollPosition = useStableCallback((y) => {
52
+ console.log('[mpx-picker-view-column], reset --->', 'columnIndex=', columnIndex, 'y=', y, touching.current, scrolling.current);
53
+ if (touching.current || scrolling.current) {
54
+ return;
55
+ }
56
+ // needReset.current = true
57
+ if (y % itemRawH !== 0) {
58
+ scrolling.current = true;
59
+ const targetIndex = getIndex(y);
60
+ const targetY = getYofIndex(targetIndex);
61
+ scrollViewRef.current?.scrollTo({ x: 0, y: targetY, animated: false });
62
+ }
63
+ else {
64
+ onMomentumScrollEnd({ nativeEvent: { contentOffset: { y } } });
65
+ }
66
+ });
67
+ const debounceResetScrollPosition = useDebounceCallback(stableResetScrollPosition, 10);
55
68
  useEffect(() => {
56
- // console.log('[mpx-picker-view-column], useEffect000 --->', 'columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'prevIndex=', prevIndex, 'activeIndex=', activeIndex.current, 'maxIndex=', maxIndex, 'prevMaxIndex=', prevMaxIndex)
57
69
  if (!scrollViewRef.current ||
58
70
  !itemRawH ||
59
71
  touching.current ||
@@ -64,84 +76,64 @@ const _PickerViewColumn = forwardRef((props, ref) => {
64
76
  maxIndex !== prevMaxIndex) {
65
77
  return;
66
78
  }
67
- // console.log('[mpx-picker-view-column], useEffect ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'y=', itemRawH * initialIndex, `${scrollViewRef.current?.scrollTo}`)
68
79
  setTimeout(() => {
69
80
  scrollViewRef.current?.scrollTo({
70
81
  x: 0,
71
- y: itemRawH * initialIndex,
82
+ y: getYofIndex(initialIndex),
72
83
  animated: false
73
84
  });
74
85
  }, isAndroid ? 200 : 0);
75
86
  activeIndex.current = initialIndex;
76
87
  }, [itemRawH, initialIndex]);
77
88
  const onContentSizeChange = (_w, h) => {
78
- const y = itemRawH * initialIndex;
79
- // console.log('[mpx-picker-view-column], onContentSizeChange --->', 'columnIndex=', columnIndex, '_w=', _w, 'h=', h, 'y=', y, 'itemRawH=', itemRawH)
89
+ const y = getYofIndex(initialIndex);
80
90
  if (y <= h) {
81
91
  setTimeout(() => {
82
92
  scrollViewRef.current?.scrollTo({ x: 0, y, animated: false });
83
93
  }, 0);
84
94
  }
85
95
  };
86
- const onScrollViewLayout = (e) => {
87
- if (isAndroid) {
88
- return;
89
- }
90
- // RN iOS bug: https://github.com/facebook/react-native/issues/36135
91
- const { width } = e.nativeEvent.layout;
92
- const widthInt = Math.ceil(width);
93
- // console.log('[mpx-picker-view-column], onScrollViewLayout --->', 'columnIndex=', columnIndex, 'width=', width, 'widthInt=', widthInt, 'scrollViewWidth=', scrollViewWidth)
94
- if (widthInt !== scrollViewWidth) {
95
- const maxW = maxScrollViewWidth.current;
96
- if (maxW !== -1 && widthInt > maxW) {
97
- return;
98
- }
99
- if (maxW === -1) {
100
- maxScrollViewWidth.current = Math.ceil(widthInt * 1.5);
101
- }
102
- setScrollViewWidth(widthInt);
103
- }
104
- if (itemRawW === '100%') {
105
- setItemRawW(widthInt);
106
- }
107
- };
108
96
  const onItemLayout = (e) => {
109
97
  const { height: rawH } = e.nativeEvent.layout;
110
- // console.log('[mpx-picker-view-column], onItemLayout --->', 'columnIndex=', columnIndex, 'width=', width)
111
98
  if (rawH && itemRawH !== rawH) {
112
99
  setItemRawH(rawH);
113
100
  }
114
101
  };
115
- const onTouchStart = () => {
102
+ const onScrollBeginDrag = () => {
103
+ isIOS && debounceResetScrollPosition.clear();
116
104
  touching.current = true;
117
105
  prevScrollingInfo.current = {
118
106
  index: activeIndex.current,
119
- y: activeIndex.current * itemRawH
107
+ y: getYofIndex(activeIndex.current)
120
108
  };
121
109
  };
122
- const onTouchEnd = () => {
123
- touching.current = false;
124
- };
125
- const onTouchCancel = () => {
110
+ const onScrollEndDrag = (e) => {
126
111
  touching.current = false;
112
+ const { y } = e.nativeEvent.contentOffset;
113
+ if (isIOS) {
114
+ if (y > 0 && y < snapToOffsets[maxIndex]) {
115
+ debounceResetScrollPosition(y);
116
+ }
117
+ }
127
118
  };
128
119
  const onMomentumScrollBegin = () => {
120
+ isIOS && debounceResetScrollPosition.clear();
129
121
  scrolling.current = true;
130
122
  };
131
123
  const onMomentumScrollEnd = (e) => {
132
124
  scrolling.current = false;
133
- if (!itemRawH) {
134
- return;
135
- }
136
125
  const { y: scrollY } = e.nativeEvent.contentOffset;
137
- let calcIndex = Math.round(scrollY / itemRawH);
126
+ if (isIOS && scrollY % itemRawH !== 0) {
127
+ return debounceResetScrollPosition(scrollY);
128
+ }
129
+ const calcIndex = getIndex(scrollY);
138
130
  activeIndex.current = calcIndex;
139
131
  if (calcIndex !== initialIndex) {
140
- calcIndex = Math.max(0, Math.min(calcIndex, maxIndex)) || 0;
141
132
  onSelectChange(calcIndex);
142
133
  }
143
134
  };
144
135
  const onScroll = (e) => {
136
+ const { y } = e.nativeEvent.contentOffset;
145
137
  if (isAndroid) {
146
138
  return;
147
139
  }
@@ -150,7 +142,6 @@ const _PickerViewColumn = forwardRef((props, ref) => {
150
142
  if (typeof pickerVibrate !== 'function') {
151
143
  return;
152
144
  }
153
- const { y } = e.nativeEvent.contentOffset;
154
145
  const { index: prevIndex, y: _y } = prevScrollingInfo.current;
155
146
  if (touching.current || scrolling.current) {
156
147
  if (Math.abs(y - _y) >= itemRawH) {
@@ -158,7 +149,7 @@ const _PickerViewColumn = forwardRef((props, ref) => {
158
149
  if (currentId !== prevIndex) {
159
150
  prevScrollingInfo.current = {
160
151
  index: currentId,
161
- y: currentId * itemRawH
152
+ y: getYofIndex(currentId)
162
153
  };
163
154
  // vibrateShort({ type: 'selection' })
164
155
  pickerVibrate();
@@ -167,11 +158,11 @@ const _PickerViewColumn = forwardRef((props, ref) => {
167
158
  }
168
159
  };
169
160
  const renderInnerchild = () => columnData.map((item, index) => {
170
- return (<MpxPickerVIewColumnItem key={index} item={item} index={index} itemHeight={itemHeight} itemWidth={itemRawW} textStyleFromParent={textStyleFromParent} textStyle={textStyle} hasVarDec={hasVarDec} varContext={varContextRef.current} textProps={textProps} visibleCount={visibleCount} onItemLayout={onItemLayout}/>);
161
+ return (<MpxPickerVIewColumnItem key={index} item={item} index={index} itemHeight={itemHeight} textStyleFromParent={textStyleFromParent} textStyle={textStyle} hasVarDec={hasVarDec} varContext={varContextRef.current} textProps={textProps} visibleCount={visibleCount} onItemLayout={onItemLayout}/>);
171
162
  });
172
163
  const renderScollView = () => {
173
164
  return (<PickerViewColumnAnimationContext.Provider value={offsetYShared}>
174
- <Reanimated.ScrollView ref={scrollViewRef} bounces={true} horizontal={false} nestedScrollEnabled={true} removeClippedSubviews={false} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} scrollEventThrottle={16} {...layoutProps} style={[{ width: scrollViewWidth }]} decelerationRate="fast" snapToOffsets={snapToOffsets} onScroll={onScroll} onLayout={onScrollViewLayout} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} onTouchCancel={onTouchCancel} onMomentumScrollBegin={onMomentumScrollBegin} onMomentumScrollEnd={onMomentumScrollEnd} onContentSizeChange={onContentSizeChange} contentContainerStyle={contentContainerStyle}>
165
+ <Reanimated.ScrollView ref={scrollViewRef} bounces={true} horizontal={false} nestedScrollEnabled={true} removeClippedSubviews={false} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} scrollEventThrottle={16} {...layoutProps} style={[{ width: '100%' }]} decelerationRate="fast" snapToOffsets={snapToOffsets} onScroll={onScroll} onScrollBeginDrag={onScrollBeginDrag} onScrollEndDrag={onScrollEndDrag} onMomentumScrollBegin={onMomentumScrollBegin} onMomentumScrollEnd={onMomentumScrollEnd} onContentSizeChange={onContentSizeChange} contentContainerStyle={contentContainerStyle}>
175
166
  {renderInnerchild()}
176
167
  </Reanimated.ScrollView>
177
168
  </PickerViewColumnAnimationContext.Provider>);
@@ -32,7 +32,7 @@
32
32
  * ✔ bindscroll
33
33
  */
34
34
  import { ScrollView } from 'react-native-gesture-handler';
35
- import { RefreshControl } from 'react-native';
35
+ import { RefreshControl, Platform } from 'react-native';
36
36
  import { useRef, useState, useEffect, forwardRef, useContext, createElement, useMemo } from 'react';
37
37
  import { useAnimatedRef } from 'react-native-reanimated';
38
38
  import { warn } from '@mpxjs/utils';
@@ -184,6 +184,7 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
184
184
  visibleLength
185
185
  });
186
186
  }
187
+ const observerTimers = {};
187
188
  function onScroll(e) {
188
189
  const { bindscroll } = props;
189
190
  const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset;
@@ -203,7 +204,16 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
203
204
  updateScrollOptions(e, { scrollLeft, scrollTop });
204
205
  if (enableTriggerIntersectionObserver && intersectionObservers) {
205
206
  for (const key in intersectionObservers) {
206
- intersectionObservers[key].throttleMeasure();
207
+ if (Platform.OS === 'android') {
208
+ intersectionObservers[key].throttleMeasure();
209
+ }
210
+ else {
211
+ // TODO: 由于iOS在onScroll滚动的过程中view的计算measureInWindow计算的值不发生变化,所以暂时在ios上加一个延时计算
212
+ observerTimers[key] && clearTimeout(observerTimers[key]);
213
+ observerTimers[key] = setTimeout(() => {
214
+ intersectionObservers[key].throttleMeasure();
215
+ }, 300);
216
+ }
207
217
  }
208
218
  }
209
219
  }
@@ -62,7 +62,7 @@ const _WebView = forwardRef((props, ref) => {
62
62
  src: res.nativeEvent?.url
63
63
  }
64
64
  };
65
- bindload(result);
65
+ bindload?.(result);
66
66
  };
67
67
  const _error = function (res) {
68
68
  const result = {
@@ -72,7 +72,7 @@ const _WebView = forwardRef((props, ref) => {
72
72
  src: ''
73
73
  }
74
74
  };
75
- binderror(result);
75
+ binderror?.(result);
76
76
  };
77
77
  const injectedJavaScript = `
78
78
  if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
@@ -451,13 +451,14 @@ export function wrapChildren(props = {}, { hasVarDec, varContext, textStyle, tex
451
451
  export const debounce = (func, delay) => {
452
452
  let timer;
453
453
  const wrapper = (...args) => {
454
- clearTimeout(timer);
454
+ timer && clearTimeout(timer);
455
455
  timer = setTimeout(() => {
456
456
  func(...args);
457
457
  }, delay);
458
458
  };
459
459
  wrapper.clear = () => {
460
- clearTimeout(timer);
460
+ timer && clearTimeout(timer);
461
+ timer = null;
461
462
  };
462
463
  return wrapper;
463
464
  };
@@ -9,7 +9,7 @@ interface PickerColumnItemProps {
9
9
  item: React.ReactElement
10
10
  index: number
11
11
  itemHeight: number
12
- itemWidth: number | '100%'
12
+ itemWidth?: number | '100%'
13
13
  textStyleFromParent: Record<string, any>
14
14
  textStyle: Record<string, any>
15
15
  hasVarDec: boolean
@@ -23,7 +23,7 @@ const _PickerViewColumnItem: React.FC<PickerColumnItemProps> = ({
23
23
  item,
24
24
  index,
25
25
  itemHeight,
26
- itemWidth,
26
+ itemWidth = '100%',
27
27
  textStyleFromParent,
28
28
  textStyle,
29
29
  hasVarDec,
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react'
2
2
  import { LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, SafeAreaView, ScrollView, StyleSheet, View } from 'react-native'
3
3
  import Reanimated, { AnimatedRef, useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'
4
- import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid } from './utils'
4
+ import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid, useDebounceCallback, useStableCallback, isIOS } from './utils'
5
5
  import useNodesRef, { HandlerRef } from './useNodesRef'
6
6
  import PickerOverlay from './pickerViewOverlay'
7
7
  import PickerMask from './pickerViewMask'
@@ -64,11 +64,8 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
64
64
  })
65
65
 
66
66
  const { height: pickerH, itemHeight } = wrapperStyle
67
- const [scrollViewWidth, setScrollViewWidth] = useState<number | '100%'>('100%')
68
- const [itemRawW, setItemRawW] = useState<number | '100%'>('100%')
69
67
  const [itemRawH, setItemRawH] = useState(itemHeight)
70
68
  const maxIndex = useMemo(() => columnData.length - 1, [columnData])
71
- const maxScrollViewWidth = useRef(-1)
72
69
  const prevScrollingInfo = useRef({ index: initialIndex, y: 0 })
73
70
  const touching = useRef(false)
74
71
  const scrolling = useRef(false)
@@ -88,11 +85,6 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
88
85
 
89
86
  // console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length, 'pickerH=', pickerH, 'itemRawH=', itemRawH, 'itemHeight=', itemHeight)
90
87
 
91
- // const initialOffset = useMemo(() => ({
92
- // x: 0,
93
- // y: itemRawH * initialIndex
94
- // }), [itemRawH])
95
-
96
88
  const paddingHeight = useMemo(
97
89
  () => Math.round((pickerH - itemHeight) / 2),
98
90
  [pickerH, itemHeight]
@@ -112,8 +104,28 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
112
104
  return Math.max(0, Math.min(calc, maxIndex))
113
105
  }, [itemRawH, maxIndex])
114
106
 
107
+ const getYofIndex = useCallback((index: number) => {
108
+ return index * itemRawH
109
+ }, [itemRawH])
110
+
111
+ const stableResetScrollPosition = useStableCallback((y: number) => {
112
+ console.log('[mpx-picker-view-column], reset --->', 'columnIndex=', columnIndex, 'y=', y, touching.current, scrolling.current)
113
+ if (touching.current || scrolling.current) {
114
+ return
115
+ }
116
+ // needReset.current = true
117
+ if (y % itemRawH !== 0) {
118
+ scrolling.current = true
119
+ const targetIndex = getIndex(y)
120
+ const targetY = getYofIndex(targetIndex)
121
+ scrollViewRef.current?.scrollTo({ x: 0, y: targetY, animated: false })
122
+ } else {
123
+ onMomentumScrollEnd({ nativeEvent: { contentOffset: { y } } })
124
+ }
125
+ })
126
+ const debounceResetScrollPosition = useDebounceCallback(stableResetScrollPosition, 10)
127
+
115
128
  useEffect(() => {
116
- // console.log('[mpx-picker-view-column], useEffect000 --->', 'columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'prevIndex=', prevIndex, 'activeIndex=', activeIndex.current, 'maxIndex=', maxIndex, 'prevMaxIndex=', prevMaxIndex)
117
129
  if (
118
130
  !scrollViewRef.current ||
119
131
  !itemRawH ||
@@ -126,11 +138,10 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
126
138
  ) {
127
139
  return
128
140
  }
129
- // console.log('[mpx-picker-view-column], useEffect ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'y=', itemRawH * initialIndex, `${scrollViewRef.current?.scrollTo}`)
130
141
  setTimeout(() => {
131
142
  scrollViewRef.current?.scrollTo({
132
143
  x: 0,
133
- y: itemRawH * initialIndex,
144
+ y: getYofIndex(initialIndex),
134
145
  animated: false
135
146
  })
136
147
  }, isAndroid ? 200 : 0)
@@ -138,8 +149,7 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
138
149
  }, [itemRawH, initialIndex])
139
150
 
140
151
  const onContentSizeChange = (_w: number, h: number) => {
141
- const y = itemRawH * initialIndex
142
- // console.log('[mpx-picker-view-column], onContentSizeChange --->', 'columnIndex=', columnIndex, '_w=', _w, 'h=', h, 'y=', y, 'itemRawH=', itemRawH)
152
+ const y = getYofIndex(initialIndex)
143
153
  if (y <= h) {
144
154
  setTimeout(() => {
145
155
  scrollViewRef.current?.scrollTo({ x: 0, y, animated: false })
@@ -147,72 +157,52 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
147
157
  }
148
158
  }
149
159
 
150
- const onScrollViewLayout = (e: LayoutChangeEvent) => {
151
- if (isAndroid) {
152
- return
153
- }
154
- // RN iOS bug: https://github.com/facebook/react-native/issues/36135
155
- const { width } = e.nativeEvent.layout
156
- const widthInt = Math.ceil(width)
157
- // console.log('[mpx-picker-view-column], onScrollViewLayout --->', 'columnIndex=', columnIndex, 'width=', width, 'widthInt=', widthInt, 'scrollViewWidth=', scrollViewWidth)
158
- if (widthInt !== scrollViewWidth) {
159
- const maxW = maxScrollViewWidth.current
160
- if (maxW !== -1 && widthInt > maxW) {
161
- return
162
- }
163
- if (maxW === -1) {
164
- maxScrollViewWidth.current = Math.ceil(widthInt * 1.5)
165
- }
166
- setScrollViewWidth(widthInt)
167
- }
168
- if (itemRawW === '100%') {
169
- setItemRawW(widthInt)
170
- }
171
- }
172
-
173
160
  const onItemLayout = (e: LayoutChangeEvent) => {
174
161
  const { height: rawH } = e.nativeEvent.layout
175
- // console.log('[mpx-picker-view-column], onItemLayout --->', 'columnIndex=', columnIndex, 'width=', width)
176
162
  if (rawH && itemRawH !== rawH) {
177
163
  setItemRawH(rawH)
178
164
  }
179
165
  }
180
166
 
181
- const onTouchStart = () => {
167
+ const onScrollBeginDrag = () => {
168
+ isIOS && debounceResetScrollPosition.clear()
182
169
  touching.current = true
183
170
  prevScrollingInfo.current = {
184
171
  index: activeIndex.current,
185
- y: activeIndex.current * itemRawH
172
+ y: getYofIndex(activeIndex.current)
186
173
  }
187
174
  }
188
175
 
189
- const onTouchEnd = () => {
190
- touching.current = false
191
- }
192
-
193
- const onTouchCancel = () => {
176
+ const onScrollEndDrag = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
194
177
  touching.current = false
178
+ const { y } = e.nativeEvent.contentOffset
179
+ if (isIOS) {
180
+ if (y > 0 && y < snapToOffsets[maxIndex]) {
181
+ debounceResetScrollPosition(y)
182
+ }
183
+ }
195
184
  }
196
185
 
197
186
  const onMomentumScrollBegin = () => {
187
+ isIOS && debounceResetScrollPosition.clear()
198
188
  scrolling.current = true
199
189
  }
200
190
 
201
- const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
191
+ const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent> | { nativeEvent: { contentOffset: { y: number } } }) => {
202
192
  scrolling.current = false
203
- if (!itemRawH) {
204
- return
205
- }
206
193
  const { y: scrollY } = e.nativeEvent.contentOffset
207
- let calcIndex = Math.round(scrollY / itemRawH)
194
+ if (isIOS && scrollY % itemRawH !== 0) {
195
+ return debounceResetScrollPosition(scrollY)
196
+ }
197
+ const calcIndex = getIndex(scrollY)
208
198
  activeIndex.current = calcIndex
209
199
  if (calcIndex !== initialIndex) {
210
- calcIndex = Math.max(0, Math.min(calcIndex, maxIndex)) || 0
211
200
  onSelectChange(calcIndex)
212
201
  }
213
202
  }
214
203
 
215
204
  const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
205
+ const { y } = e.nativeEvent.contentOffset
216
206
  if (isAndroid) {
217
207
  return
218
208
  }
@@ -221,7 +211,6 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
221
211
  if (typeof pickerVibrate !== 'function') {
222
212
  return
223
213
  }
224
- const { y } = e.nativeEvent.contentOffset
225
214
  const { index: prevIndex, y: _y } = prevScrollingInfo.current
226
215
  if (touching.current || scrolling.current) {
227
216
  if (Math.abs(y - _y) >= itemRawH) {
@@ -229,7 +218,7 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
229
218
  if (currentId !== prevIndex) {
230
219
  prevScrollingInfo.current = {
231
220
  index: currentId,
232
- y: currentId * itemRawH
221
+ y: getYofIndex(currentId)
233
222
  }
234
223
  // vibrateShort({ type: 'selection' })
235
224
  pickerVibrate()
@@ -246,7 +235,6 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
246
235
  item={item}
247
236
  index={index}
248
237
  itemHeight={itemHeight}
249
- itemWidth={itemRawW}
250
238
  textStyleFromParent={textStyleFromParent}
251
239
  textStyle={textStyle}
252
240
  hasVarDec={hasVarDec}
@@ -271,14 +259,12 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
271
259
  showsHorizontalScrollIndicator={false}
272
260
  scrollEventThrottle={16}
273
261
  {...layoutProps}
274
- style={[{ width: scrollViewWidth }]}
262
+ style={[{ width: '100%' }]}
275
263
  decelerationRate="fast"
276
264
  snapToOffsets={snapToOffsets}
277
265
  onScroll={onScroll}
278
- onLayout={onScrollViewLayout}
279
- onTouchStart={onTouchStart}
280
- onTouchEnd={onTouchEnd}
281
- onTouchCancel={onTouchCancel}
266
+ onScrollBeginDrag={onScrollBeginDrag}
267
+ onScrollEndDrag={onScrollEndDrag}
282
268
  onMomentumScrollBegin={onMomentumScrollBegin}
283
269
  onMomentumScrollEnd={onMomentumScrollEnd}
284
270
  onContentSizeChange={onContentSizeChange}
@@ -32,7 +32,7 @@
32
32
  * ✔ bindscroll
33
33
  */
34
34
  import { ScrollView } from 'react-native-gesture-handler'
35
- import { View, RefreshControl, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle } from 'react-native'
35
+ import { View, RefreshControl, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle, Platform } from 'react-native'
36
36
  import { JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef, useContext, createElement, useMemo } from 'react'
37
37
  import { useAnimatedRef } from 'react-native-reanimated'
38
38
  import { warn } from '@mpxjs/utils'
@@ -40,7 +40,6 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners'
40
40
  import useNodesRef, { HandlerRef } from './useNodesRef'
41
41
  import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, GestureHandler } from './utils'
42
42
  import { IntersectionObserverContext, ScrollViewContext } from './context'
43
-
44
43
  interface ScrollViewProps {
45
44
  children?: ReactNode;
46
45
  enhanced?: boolean;
@@ -319,6 +318,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
319
318
  })
320
319
  }
321
320
 
321
+ const observerTimers: {[key: string]: any} = {}
322
322
  function onScroll (e: NativeSyntheticEvent<NativeScrollEvent>) {
323
323
  const { bindscroll } = props
324
324
  const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset
@@ -340,7 +340,15 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
340
340
  updateScrollOptions(e, { scrollLeft, scrollTop })
341
341
  if (enableTriggerIntersectionObserver && intersectionObservers) {
342
342
  for (const key in intersectionObservers) {
343
- intersectionObservers[key].throttleMeasure()
343
+ if (Platform.OS === 'android') {
344
+ intersectionObservers[key].throttleMeasure();
345
+ } else {
346
+ // TODO: 由于iOS在onScroll滚动的过程中view的计算measureInWindow计算的值不发生变化,所以暂时在ios上加一个延时计算
347
+ observerTimers[key] && clearTimeout(observerTimers[key])
348
+ observerTimers[key] = setTimeout(() => {
349
+ intersectionObservers[key].throttleMeasure();
350
+ }, 300)
351
+ }
344
352
  }
345
353
  }
346
354
  }
@@ -60,17 +60,17 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
60
60
  const canGoBack = useRef<boolean>(false)
61
61
 
62
62
  const onAndroidBackPress = useCallback(() => {
63
- if (canGoBack.current) {
64
- webViewRef.current?.goBack()
65
- return true
66
- }
67
- return false
63
+ if (canGoBack.current) {
64
+ webViewRef.current?.goBack()
65
+ return true
66
+ }
67
+ return false
68
68
  }, [canGoBack])
69
69
 
70
70
  const beforeRemoveHandle = useCallback((e: Event) => {
71
71
  if (canGoBack.current) {
72
- webViewRef.current?.goBack()
73
- e.preventDefault()
72
+ webViewRef.current?.goBack()
73
+ e.preventDefault()
74
74
  }
75
75
  }, [canGoBack])
76
76
 
@@ -80,10 +80,10 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
80
80
 
81
81
  useEffect(() => {
82
82
  if (__mpx_mode__ === 'android') {
83
- BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress)
84
- return () => {
85
- BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress)
86
- }
83
+ BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress)
84
+ return () => {
85
+ BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress)
86
+ }
87
87
  }
88
88
  }, [])
89
89
 
@@ -103,7 +103,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
103
103
  src: res.nativeEvent?.url
104
104
  }
105
105
  }
106
- bindload(result)
106
+ bindload?.(result)
107
107
  }
108
108
  const _error = function (res: WebViewErrorEvent) {
109
109
  const result = {
@@ -113,7 +113,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
113
113
  src: ''
114
114
  }
115
115
  }
116
- binderror(result)
116
+ binderror?.(result)
117
117
  }
118
118
  const injectedJavaScript = `
119
119
  if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
@@ -141,7 +141,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
141
141
  }
142
142
  true;
143
143
  `
144
- const sendMessage = function(params: string) {
144
+ const sendMessage = function (params: string) {
145
145
  return `
146
146
  window.mpxWebviewMessageCallback(${params})
147
147
  true;
@@ -156,7 +156,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
156
156
 
157
157
  const _onLoadProgress = function (event: WebViewProgressEvent) {
158
158
  if (__mpx_mode__ === 'android') {
159
- canGoBack.current = event.nativeEvent.canGoBack
159
+ canGoBack.current = event.nativeEvent.canGoBack
160
160
  }
161
161
  }
162
162
  const _message = function (res: WebViewMessageEvent) {
@@ -540,13 +540,14 @@ export const debounce = <T extends AnyFunc> (
540
540
  ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
541
541
  let timer: any
542
542
  const wrapper = (...args: ReadonlyArray<any>) => {
543
- clearTimeout(timer)
543
+ timer && clearTimeout(timer)
544
544
  timer = setTimeout(() => {
545
545
  func(...args)
546
546
  }, delay)
547
547
  }
548
548
  wrapper.clear = () => {
549
- clearTimeout(timer)
549
+ timer && clearTimeout(timer)
550
+ timer = null
550
551
  }
551
552
  return wrapper
552
553
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.9.69-beta.1",
3
+ "version": "2.9.69-beta.2",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"