mirror of
https://github.com/status-im/react-native.git
synced 2025-01-14 11:34:23 +00:00
UIRefreshControl added to scroll view
Summary: **What:** adds `onRefreshStart` property to `ScrollView.js` for displaying and activating pull to refresh. **Why:** Javascript implementations seemed a little flakey and inconsistent. As you can see in the issues below: https://github.com/facebook/react-native/issues/2356 https://github.com/facebook/react-native/issues/745 So this is an attempt a completely native implementation. What do you think? ![Image of dog](http://i.imgur.com/HcTQnzJ.gif) Closes https://github.com/facebook/react-native/pull/4205 Reviewed By: svcscm Differential Revision: D2674945 Pulled By: nicklockwood fb-gh-sync-id: 65113a5db9785df5a95c68323c2cdf19f3b217b1
This commit is contained in:
parent
5950f8cf15
commit
2faf8632d3
@ -15,6 +15,7 @@ var EdgeInsetsPropType = require('EdgeInsetsPropType');
|
|||||||
var Platform = require('Platform');
|
var Platform = require('Platform');
|
||||||
var PointPropType = require('PointPropType');
|
var PointPropType = require('PointPropType');
|
||||||
var RCTScrollView = require('NativeModules').UIManager.RCTScrollView;
|
var RCTScrollView = require('NativeModules').UIManager.RCTScrollView;
|
||||||
|
var RCTScrollViewManager = require('NativeModules').ScrollViewManager;
|
||||||
var React = require('React');
|
var React = require('React');
|
||||||
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
|
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
|
||||||
var RCTUIManager = require('NativeModules').UIManager;
|
var RCTUIManager = require('NativeModules').UIManager;
|
||||||
@ -279,6 +280,21 @@ var ScrollView = React.createClass({
|
|||||||
* @platform ios
|
* @platform ios
|
||||||
*/
|
*/
|
||||||
zoomScale: PropTypes.number,
|
zoomScale: PropTypes.number,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When defined, displays a UIRefreshControl.
|
||||||
|
* Invoked with a function to stop refreshing when the UIRefreshControl is animating.
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* (endRefreshing) => {
|
||||||
|
* endRefreshing();
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @platform ios
|
||||||
|
*/
|
||||||
|
onRefreshStart: PropTypes.func,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [ScrollResponder.Mixin],
|
mixins: [ScrollResponder.Mixin],
|
||||||
@ -291,6 +307,12 @@ var ScrollView = React.createClass({
|
|||||||
this.refs[SCROLLVIEW].setNativeProps(props);
|
this.refs[SCROLLVIEW].setNativeProps(props);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
endRefreshing: function() {
|
||||||
|
RCTScrollViewManager.endRefreshing(
|
||||||
|
React.findNodeHandle(this)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a reference to the underlying scroll responder, which supports
|
* Returns a reference to the underlying scroll responder, which supports
|
||||||
* operations like `scrollTo`. All ScrollView-like components should
|
* operations like `scrollTo`. All ScrollView-like components should
|
||||||
@ -396,6 +418,13 @@ var ScrollView = React.createClass({
|
|||||||
onResponderReject: this.scrollResponderHandleResponderReject,
|
onResponderReject: this.scrollResponderHandleResponderReject,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var onRefreshStart = this.props.onRefreshStart;
|
||||||
|
// this is necessary because if we set it on props, even when empty,
|
||||||
|
// it'll trigger the default pull-to-refresh behaviour on native.
|
||||||
|
props.onRefreshStart = onRefreshStart
|
||||||
|
? function() { onRefreshStart && onRefreshStart(this.endRefreshing); }.bind(this)
|
||||||
|
: null;
|
||||||
|
|
||||||
var ScrollViewClass;
|
var ScrollViewClass;
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
ScrollViewClass = RCTScrollView;
|
ScrollViewClass = RCTScrollView;
|
||||||
|
@ -47,6 +47,9 @@
|
|||||||
@property (nonatomic, assign) int snapToInterval;
|
@property (nonatomic, assign) int snapToInterval;
|
||||||
@property (nonatomic, copy) NSString *snapToAlignment;
|
@property (nonatomic, copy) NSString *snapToAlignment;
|
||||||
@property (nonatomic, copy) NSIndexSet *stickyHeaderIndices;
|
@property (nonatomic, copy) NSIndexSet *stickyHeaderIndices;
|
||||||
|
@property (nonatomic, copy) RCTDirectEventBlock onRefreshStart;
|
||||||
|
|
||||||
|
- (void)endRefreshing;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||||||
|
|
||||||
@property (nonatomic, copy) NSIndexSet *stickyHeaderIndices;
|
@property (nonatomic, copy) NSIndexSet *stickyHeaderIndices;
|
||||||
@property (nonatomic, assign) BOOL centerContent;
|
@property (nonatomic, assign) BOOL centerContent;
|
||||||
|
@property (nonatomic, strong) UIRefreshControl *refreshControl;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -352,6 +353,15 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||||||
return hitView ?: [super hitTest:point withEvent:event];
|
return hitView ?: [super hitTest:point withEvent:event];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setRefreshControl:(UIRefreshControl *)refreshControl
|
||||||
|
{
|
||||||
|
if (_refreshControl) {
|
||||||
|
[_refreshControl removeFromSuperview];
|
||||||
|
}
|
||||||
|
_refreshControl = refreshControl;
|
||||||
|
[self addSubview:_refreshControl];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RCTScrollView
|
@implementation RCTScrollView
|
||||||
@ -844,6 +854,34 @@ RCT_SET_AND_PRESERVE_OFFSET(setScrollIndicatorInsets, UIEdgeInsets);
|
|||||||
return [_scrollView valueForKey:key];
|
return [_scrollView valueForKey:key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setOnRefreshStart:(RCTDirectEventBlock)onRefreshStart
|
||||||
|
{
|
||||||
|
if (!onRefreshStart) {
|
||||||
|
_onRefreshStart = nil;
|
||||||
|
_scrollView.refreshControl = nil;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_onRefreshStart = [onRefreshStart copy];
|
||||||
|
|
||||||
|
if (!_scrollView.refreshControl) {
|
||||||
|
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
|
||||||
|
[refreshControl addTarget:self action:@selector(refreshControlValueChanged) forControlEvents:UIControlEventValueChanged];
|
||||||
|
_scrollView.refreshControl = refreshControl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refreshControlValueChanged
|
||||||
|
{
|
||||||
|
if (self.onRefreshStart) {
|
||||||
|
self.onRefreshStart(nil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)endRefreshing
|
||||||
|
{
|
||||||
|
[_scrollView.refreshControl endRefreshing];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RCTEventDispatcher (RCTScrollView)
|
@implementation RCTEventDispatcher (RCTScrollView)
|
||||||
|
@ -65,6 +65,7 @@ RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets, UIEdgeInsets)
|
|||||||
RCT_EXPORT_VIEW_PROPERTY(snapToInterval, int)
|
RCT_EXPORT_VIEW_PROPERTY(snapToInterval, int)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(snapToAlignment, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(snapToAlignment, NSString)
|
||||||
RCT_REMAP_VIEW_PROPERTY(contentOffset, scrollView.contentOffset, CGPoint)
|
RCT_REMAP_VIEW_PROPERTY(contentOffset, scrollView.contentOffset, CGPoint)
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(onRefreshStart, RCTDirectEventBlock)
|
||||||
|
|
||||||
- (NSDictionary<NSString *, id> *)constantsToExport
|
- (NSDictionary<NSString *, id> *)constantsToExport
|
||||||
{
|
{
|
||||||
@ -114,6 +115,22 @@ RCT_EXPORT_METHOD(calculateChildFrames:(nonnull NSNumber *)reactTag
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(endRefreshing:(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 endRefreshing];
|
||||||
|
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSArray<NSString *> *)customDirectEventTypes
|
- (NSArray<NSString *> *)customDirectEventTypes
|
||||||
{
|
{
|
||||||
return @[
|
return @[
|
||||||
@ -127,3 +144,4 @@ RCT_EXPORT_METHOD(calculateChildFrames:(nonnull NSNumber *)reactTag
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user