更改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];
}