react native自定义下拉刷新——桥接MJRefresh

因使用iOS原生UIRefreshControl会出现卡住问题

基础可参考此篇文章

https://cloud.tencent.com/developer/article/1129267

OC部分不同处
  • layoutsubview里面
- (void)layoutSubviews
{
  [super layoutSubviews];
  RCTAssert(self.subviews.count == 1, @"we should only have exactly one subview");
  RCTAssert([self.subviews lastObject] == _scrollView, @"our only subview should be a scrollview");

#if !TARGET_OS_TV
  // Adjust the refresh control frame if the scrollview layout changes.
  UIView *refreshControl = _scrollView.customRefreshControl;
  if (refreshControl && refreshControl.isRefreshing) {
    refreshControl.frame = (CGRect){_scrollView.contentOffset, {_scrollView.frame.size.width, refreshControl.frame.size.height}};
  }
  
  if (_scrollView.mj_header != nil && _scrollView.mj_header.isRefreshing) {
    refreshControl.frame = (CGRect){_scrollView.contentOffset, {_scrollView.frame.size.width, _scrollView.mj_header.frame.size.height}};
  }
#endif

  [self updateClippedSubviews];
}
js部分不同处
  • 添加方法时使用 this.getScrollResponder()调用
startPullToRefresh: function() {
    this.getScrollResponder().startPullToRefresh(
        ReactNative.findNodeHandle(this)
    );
  },
  
  stopPullToRefresh: function() {
    this.getScrollResponder().stopPullToRefresh(
        ReactNative.findNodeHandle(this)
    );
  },

在桥接完成基础上添加颜色支持

  1. 在RCTScrollView.m文件此方法下
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
  1. 尾部添加下面代码
if (self.whiteStyle) {
      ((MJRefreshNormalHeader *)_scrollView.mj_header).loadingView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
      ((MJRefreshNormalHeader *)_scrollView.mj_header).stateLabel.textColor = [UIColor whiteColor];
    }

如果不做抽屉,头部添加底图,需要注意视图层级问题,在后面添加,把mj_header提上来(一般情况下可忽略此步)

[_scrollView bringSubviewToFront:_scrollView.mj_header];

整体代码如下

- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
{
  [super insertReactSubview:view atIndex:atIndex];
#if !TARGET_OS_TV
  if ([view conformsToProtocol:@protocol(RCTCustomRefreshContolProtocol)]) {
    [_scrollView setCustomRefreshControl:(UIView *)view];
    if (![view isKindOfClass:[UIRefreshControl class]]
        && [view conformsToProtocol:@protocol(UIScrollViewDelegate)]) {
      [self addScrollListener:(UIView *)view];
    }
  } else
#endif
  {
    RCTAssert(_contentView == nil, @"RCTScrollView may only contain a single subview");
    _contentView = view;
    RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection);
    [_scrollView addSubview:view];
    if (self.whiteStyle) {
      ((MJRefreshNormalHeader *)_scrollView.mj_header).loadingView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
      ((MJRefreshNormalHeader *)_scrollView.mj_header).stateLabel.textColor = [UIColor whiteColor];
    }
    [_scrollView bringSubviewToFront:_scrollView.mj_header];
  }
}
  1. RCTScrollView.h 文件下添加属性支持
@property (nonatomic, assign) BOOL whiteStyle;

RCTScrollViewManager文件配置

RCTScrollViewManager.m 导出属性给react-native中使用

RCT_EXPORT_VIEW_PROPERTY(whiteStyle, BOOL)

react-native 中添加属性支持

./node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js ScrollView.js的IOSProps中添加

whiteStyle: PropTypes.bool,

如果是使用ts

./node_modules/@types/react-native/index.d.tsScrollViewPropsIOS 中添加

whiteStyle?: boolean

测试通过的react-native版本:0.57.8

再次提醒,因为是做iOS支持,在react-native中需要做平台判断


你可能感兴趣的:(react native自定义下拉刷新——桥接MJRefresh)