Add support for flashScrollIndicators on iOS
Summary: Flashing scroll indicators is a standard behavior on iOS to show the user there's more content. Launch RNTester on iOS, go to the ScrollView section, tap the "Flash scroll indicators" button. You'll see this:  I've exposed the method `flashScrollIndicators` on all scrolling components that were already exposing a `scrollToXXX` method so it's usable from those components using a ref. Let me know what you think. Closes https://github.com/facebook/react-native/pull/14058 Differential Revision: D5103239 Pulled By: shergin fbshipit-source-id: caad8474fbe475065418d771b17e4ea9766ffcdc
@ -465,6 +465,16 @@ var ScrollResponderMixin = {
|
|||||||
ScrollViewManager.zoomToRect(this.scrollResponderGetScrollableNode(), rect, animated !== false);
|
ScrollViewManager.zoomToRect(this.scrollResponderGetScrollableNode(), rect, animated !== false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the scroll indicators momentarily.
|
||||||
|
*
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
scrollResponderFlashScrollIndicators: function() {
|
||||||
|
invariant(ScrollViewManager && ScrollViewManager.flashScrollIndicators, 'flashScrollIndicators is not implemented');
|
||||||
|
ScrollViewManager.flashScrollIndicators(this.scrollResponderGetScrollableNode());
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method should be used as the callback to onFocus in a TextInputs'
|
* This method should be used as the callback to onFocus in a TextInputs'
|
||||||
* parent view. Note that any module using this mixin needs to return
|
* parent view. Note that any module using this mixin needs to return
|
||||||
|
@ -495,6 +495,15 @@ const ScrollView = React.createClass({
|
|||||||
this.scrollTo({x, y, animated: false});
|
this.scrollTo({x, y, animated: false});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the scroll indicators momentarily.
|
||||||
|
*
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
flashScrollIndicators: function() {
|
||||||
|
this.getScrollResponder().scrollResponderFlashScrollIndicators();
|
||||||
|
},
|
||||||
|
|
||||||
_getKeyForIndex: function(index, childArray) {
|
_getKeyForIndex: function(index, childArray) {
|
||||||
const child = childArray[index];
|
const child = childArray[index];
|
||||||
return child && child.key;
|
return child && child.key;
|
||||||
|
@ -342,6 +342,15 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
|
|||||||
this._listRef.recordInteraction();
|
this._listRef.recordInteraction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the scroll indicators momentarily.
|
||||||
|
*
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
flashScrollIndicators() {
|
||||||
|
this._listRef.flashScrollIndicators();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a handle to the underlying scroll responder.
|
* Provides a handle to the underlying scroll responder.
|
||||||
*/
|
*/
|
||||||
|
@ -292,6 +292,17 @@ var ListView = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the scroll indicators momentarily.
|
||||||
|
*
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
flashScrollIndicators: function() {
|
||||||
|
if (this._scrollComponent && this._scrollComponent.flashScrollIndicators) {
|
||||||
|
this._scrollComponent.flashScrollIndicators();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setNativeProps: function(props: Object) {
|
setNativeProps: function(props: Object) {
|
||||||
if (this._scrollComponent) {
|
if (this._scrollComponent) {
|
||||||
this._scrollComponent.setNativeProps(props);
|
this._scrollComponent.setNativeProps(props);
|
||||||
|
@ -283,6 +283,16 @@ class SectionList<SectionT: SectionBase<any>>
|
|||||||
listRef && listRef.recordInteraction();
|
listRef && listRef.recordInteraction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the scroll indicators momentarily.
|
||||||
|
*
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
flashScrollIndicators() {
|
||||||
|
const listRef = this._wrapperListRef && this._wrapperListRef.getListRef();
|
||||||
|
listRef && listRef.flashScrollIndicators();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a handle to the underlying scroll responder.
|
* Provides a handle to the underlying scroll responder.
|
||||||
*/
|
*/
|
||||||
|
@ -260,6 +260,10 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
|
|||||||
this._updateViewableItems(this.props.data);
|
this._updateViewableItems(this.props.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flashScrollIndicators() {
|
||||||
|
this._scrollRef.flashScrollIndicators();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a handle to the underlying scroll responder.
|
* Provides a handle to the underlying scroll responder.
|
||||||
* Note that `this._scrollRef` might not be a `ScrollView`, so we
|
* Note that `this._scrollRef` might not be a `ScrollView`, so we
|
||||||
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 94 KiB |
@ -14,6 +14,7 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactNative = require('react-native');
|
var ReactNative = require('react-native');
|
||||||
var {
|
var {
|
||||||
|
Platform,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
@ -51,6 +52,13 @@ exports.examples = [
|
|||||||
onPress={() => { _scrollView.scrollToEnd({animated: true}); }}>
|
onPress={() => { _scrollView.scrollToEnd({animated: true}); }}>
|
||||||
<Text>Scroll to bottom</Text>
|
<Text>Scroll to bottom</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
{ Platform.OS === 'ios' ?
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => { _scrollView.flashScrollIndicators(); }}>
|
||||||
|
<Text>Flash scroll indicators</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
: null }
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -81,6 +89,13 @@ exports.examples = [
|
|||||||
onPress={() => { _scrollView.scrollToEnd({animated: true}); }}>
|
onPress={() => { _scrollView.scrollToEnd({animated: true}); }}>
|
||||||
<Text>Scroll to end</Text>
|
<Text>Scroll to end</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
{ Platform.OS === 'ios' ?
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => { _scrollView.flashScrollIndicators(); }}>
|
||||||
|
<Text>Flash scroll indicators</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
: null }
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -178,4 +178,19 @@ RCT_EXPORT_METHOD(zoomToRect:(nonnull NSNumber *)reactTag
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(flashScrollIndicators:(nonnull NSNumber *)reactTag)
|
||||||
|
{
|
||||||
|
[self.bridge.uiManager addUIBlock:
|
||||||
|
^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTScrollView *> *viewRegistry){
|
||||||
|
|
||||||
|
RCTScrollView *view = viewRegistry[reactTag];
|
||||||
|
if (!view || ![view isKindOfClass:[RCTScrollView class]]) {
|
||||||
|
RCTLogError(@"Cannot find RCTScrollView with tag #%@", reactTag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[view.scrollView flashScrollIndicators];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|