美文网首页
React Native 使用自定义下拉刷新

React Native 使用自定义下拉刷新

作者: yeyuCoder | 来源:发表于2019-09-24 21:38 被阅读0次

    更改RN的刷新组件为MJRefresh:

    react.podspec文件

    core增加ss.dependency "MJRefresh"

    Development Pods/React/Core/Views目录

    添加PYRNRefreshHeader类

    RCTRefreshControl.h文件更新

    #import "PYRNRefreshHeader.h"

    更改继承为:PYRNRefreshHeader

    RCTRefreshControl.m文件

    替换如下代码:

    -  (instancetype)init

    {

        if  ((self  =  [super  init]))  {

            [self  setRefreshingTarget:self  refreshingAction:@selector(refreshControlValueChanged)];

            _isInitialRender  =  true;

            _currentRefreshingState  =  false;

        }

        return  self;

    }

    -  (void)setFrame:(CGRect)frame  {

        CGFloat  width  =  self.scrollView.frame.size.width  ?:  [UIScreen  mainScreen].bounds.size.width;

        CGFloat  height  =  60;

        [super  setFrame:CGRectMake(frame.origin.x,  _isInitialRender  ?  frame.origin.y  :  -60,  width,  height)];

    }

    RCT_NOT_IMPLEMENTED(-  (instancetype)initWithCoder:(NSCoder  *)aDecoder)

    -  (void)layoutSubviews

    {

        [super  layoutSubviews];

        //  Fix  for  bug  #7976

        //  TODO:  Remove  when  updating  to  use  iOS  10  refreshControl  UIScrollView  prop.

        self.backgroundColor  =  [UIColor  clearColor];

        //  by  zbwu

        BOOL iPhoneX = NO;

        if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone &&[[UIScreen mainScreen]bounds].size.height > 812){

            iPhoneX = YES;

        }

        UIWindow *window =[UIApplication sharedApplication].keyWindow;

        UIColor  *color  =  [self  colorOfPoint:CGPointMake(10,iPhoneX? 140:116)  inView:window];

        NSArray  *rgbValues  =  [self  getRGBDictionaryByColor:color];

        BOOL  showWhite  =  NO;

        for  (NSNumber  *number  in  rgbValues)  {

            CGFloat value =[number  floatValue];

            if  (value > 0 && value <  0.75)  {

                showWhite  =  YES;

                break;

            }

        }

        self.aiView.color  =  showWhite?  [UIColor  whiteColor]  :  [UIColor  lightGrayColor];

        //  If  the  control  is  refreshing  when  mounted  we  need  to  call

        //  beginRefreshing  in  layoutSubview  or  it  doesn't  work.

        if  (_currentRefreshingState  &&  _isInitialRender)  {

            [self  _beginRefreshing];

        }

        _isInitialRender  =  false;

    }

    //  by  zbwu

    -  (NSArray  *)getRGBDictionaryByColor:(UIColor  *)originColor  {

        CGFloat  r=0,  g=0,  b=0,  a=0;

        if  ([self  respondsToSelector:@selector(getRed:green:blue:alpha:)])  {

            [originColor  getRed:&r  green:&g  blue:&b  alpha:&a];

        }

        else  {

            const  CGFloat  *components  =  CGColorGetComponents(originColor.CGColor);

            r  =  components[0];

            g  =  components[1];

            b  =  components[2];

            a  =  components[3];

        }

        return  @[@(r),  @(g),  @(b)];

    }

    //  by  zbwu

    -  (UIColor  *)colorOfPoint:(CGPoint)point  inView:(UIView  *)view  {

        unsigned  char  pixel[4]  =  {0};

        CGColorSpaceRef  colorSpace  =  CGColorSpaceCreateDeviceRGB();

        CGContextRef  context  =  CGBitmapContextCreate(pixel,  1,  1,  8,  4,  colorSpace,  (CGBitmapInfo)kCGImageAlphaPremultipliedLast);

        CGContextTranslateCTM(context,  -point.x,  -point.y);

        [view.layer  renderInContext:context];

        CGContextRelease(context);

        CGColorSpaceRelease(colorSpace);

        UIColor *color =[UIColor colorWithRed:pixel[0]/255.0 green:pixel[1]/255.0 blue:pixel[2]/255.0 alpha:pixel[3]/255.0];

        return color;

    }

    -(void)_beginRefreshing

    {

        [self.scrollView.mj_header beginRefreshing];

    }

    -(void)_endRefreshing

    {

        [self.scrollView.mj_header endRefreshing];

        _currentRefreshingState = false;

    }

    -(void)beginRefreshingProgrammatically

    {

        UInt64 beginRefreshingTimestamp = _currentRefreshingStateTimestamp;

        _refreshingProgrammatically = YES;

        // When using begin refreshing we need to adjust the ScrollView content offset manually.

        UIScrollView *scrollView =(UIScrollView *)self.superview;

        CGPoint offset = {scrollView.contentOffset.x,scrollView.contentOffset.y - self.frame.size.height};

        // `beginRefreshing` must be called after the animation is done. This is why it is impossible

        // to use `setContentOffset` with `animated:YES`.

        [UIView animateWithDuration:0.25

                              delay:0

                            options:UIViewAnimationOptionBeginFromCurrentState

                         animations:^(void){

                             [scrollView setContentOffset:offset];

                         } completion:^(__unused BOOL finished){

                             if(beginRefreshingTimestamp == self->_currentRefreshingStateTimestamp){

                                 [super beginRefreshing];

                                 [self setCurrentRefreshingState:super.refreshing];

                             }

                         }];

    }

    -(void)endRefreshingProgrammatically

    {

        // The contentOffset of the scrollview MUST be greater than 0 before calling

        // endRefreshing otherwise the next pull to refresh will not work properly.

        UIScrollView *scrollView =(UIScrollView *)self.superview;

        if(_refreshingProgrammatically && scrollView.contentOffset.y < 0){

            UInt64 endRefreshingTimestamp = _currentRefreshingStateTimestamp;

            CGPoint offset = {scrollView.contentOffset.x,0};

            [UIView animateWithDuration:0.25

                                  delay:0

                                options:UIViewAnimationOptionBeginFromCurrentState

                             animations:^(void){

                                 [scrollView setContentOffset:offset];

                             } completion:^(__unused BOOL finished){

                                 if(endRefreshingTimestamp == self->_currentRefreshingStateTimestamp){

                                     [super endRefreshing];

                                     [self setCurrentRefreshingState:super.refreshing];

                                 }

                             }];

        } else {

            [super endRefreshing];

        }

    }

    -(NSString *)title

    {

        return _title;

    }

    -(void)setTitle:(NSString *)title

    {

        _title = title;

        [self _updateTitle];

    }

    -(void)setTitleColor:(UIColor *)color

    {

        _titleColor = color;

        [self _updateTitle];

    }

    -(void)_updateTitle

    {

        if(!_title){

            return;

        }

        NSMutableDictionary *attributes =[NSMutableDictionary dictionary];

        if(_titleColor){

            attributes[NSForegroundColorAttributeName]= _titleColor;

        }

        //self.attributedTitle =[[NSAttributedString alloc]initWithString:_title attributes:attributes];

    }

    -(void)setRefreshing:(BOOL)refreshing

    {

        if(_currentRefreshingState != refreshing){

            if(refreshing){

                if(!_isInitialRender){

                    [self _beginRefreshing];

                }

            } else {

                [self _endRefreshing];

            }

        }

    }

    -(void)setCurrentRefreshingState:(BOOL)refreshing

    {

        _currentRefreshingState = refreshing;

        _currentRefreshingStateTimestamp = _currentRefreshingStateClock++;

    }

    -(void)refreshControlValueChanged

    {

        _currentRefreshingState = true;

        if(_onRefresh){

            _onRefresh(nil);

        }

    }

    RCTScrollView.m文件

    RCTCustomScrollView类中,替换setCustomRefreshControl函数中的代码

    -(void)setCustomRefreshControl:(UIView *)refreshControl

    {

        _customRefreshControl = refreshControl;

        self.mj_header = refreshControl;

    }

    RCTScrollView类中,替换layoutSubviews函数#if !TARGET_OS_TV … #endif中的代码

    -(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

        RCTRefreshControl *refreshControl = _scrollView.customRefreshControl;

        if(refreshControl && refreshControl.state == MJRefreshStateIdle){

            refreshControl.frame = CGRectMake(0,-60,self.frame.size.width,60);

        }

    #endif

      [self updateClippedSubviews];

    }

    相关文章

      网友评论

          本文标题:React Native 使用自定义下拉刷新

          本文链接:https://www.haomeiwen.com/subject/iqwkdctx.html