diff --git a/SWRefresh.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SWRefresh.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/SWRefresh.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/SWRefresh/SWRefreshAutoFooterViewModel.m b/SWRefresh/SWRefreshAutoFooterViewModel.m index 1e3a0f6..686c1c7 100644 --- a/SWRefresh/SWRefreshAutoFooterViewModel.m +++ b/SWRefresh/SWRefreshAutoFooterViewModel.m @@ -64,23 +64,29 @@ __unsafe_unretained bool(^canAutoRefresh)() = ^bool{ self.state != SWRefreshStateNoMoreData && !self.scrollView.isTracking); }; - if ([self isRefreshing] || - (self.pullingLength <= 0 && !canAutoRefresh()) - ) { return; } + if ( [self isRefreshing] ) { return; } CGFloat pullingOffsetY = [self pullingOffsetY]; CGFloat offsetY = self.scrollView.contentOffset.y; - if (self.pullingLength > 0) { // 计算percent - // 开始改变pullingPercent的位置 - CGFloat happendOffsetY = pullingOffsetY - self.pullingLength; - if (offsetY < happendOffsetY) { return; } - - self.pullingPercent = (offsetY - happendOffsetY) / self.pullingLength; - - if (!canAutoRefresh()) { return; } + CGFloat pullingPercent = ^CGFloat{ + if (self.pullingLength > 0) { // 计算percent + // 开始改变pullingPercent的位置 + CGFloat happendOffsetY = pullingOffsetY - self.pullingLength; + if (offsetY < happendOffsetY) { + return 0; + } else { + return (offsetY - happendOffsetY) / self.pullingLength; + } + } else { + return offsetY > pullingOffsetY ? 1 : 0; + } + }(); + if (self.pullingPercent != pullingPercent) { + self.pullingPercent = pullingPercent; } - if (pullingOffsetY < offsetY) { + + if (pullingOffsetY < offsetY && canAutoRefresh()) { CGFloat bounceOffset = self.scrollView.contentSize.height + self.scrollView.contentInset.bottom - self.scrollView.frame.size.height; if (offsetY <= bounceOffset) { @@ -107,7 +113,13 @@ - (void)changeFromState:(SWRefreshState)oldState to:(SWRefreshState)newState { } - (CGFloat)pullingOffsetY { - UIEdgeInsets inset = self.scrollView.contentInset; + UIEdgeInsets inset = ^{ + if (@available(iOS 11.0, *)) { + return self.scrollView.adjustedContentInset; + } else { + return self.scrollView.contentInset; + } + }(); // 自动触发点在刚显示view, 加上偏移值 CGFloat bounceOffset = self.scrollView.contentSize.height + inset.bottom - self.scrollView.frame.size.height; diff --git a/SWRefresh/SWRefreshBackFooterViewModel.m b/SWRefresh/SWRefreshBackFooterViewModel.m index 59a3c23..b6e072b 100644 --- a/SWRefresh/SWRefreshBackFooterViewModel.m +++ b/SWRefresh/SWRefreshBackFooterViewModel.m @@ -40,7 +40,10 @@ - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change { CGFloat happendOffsetY = [self happendOffsetY]; // 没达到临界点 - if ( happendOffsetY > offset.y ) return; + if (happendOffsetY > offset.y) { + if (self.pullingPercent > 0) { self.pullingPercent = 0; } + return; + } CGFloat pullingPercent = (offset.y - happendOffsetY) / _refreshThreshold; diff --git a/SWRefresh/SWRefreshController.m b/SWRefresh/SWRefreshController.m index af1a1b1..848ea5d 100644 --- a/SWRefresh/SWRefreshController.m +++ b/SWRefresh/SWRefreshController.m @@ -90,13 +90,14 @@ - (void)updateHeaderViewFrame { @implementation SWRefreshFooterController - (void)dealloc { + self.footerModel = nil; self.scrollView = nil; } + (instancetype)newWithFooterView:(UIView *)footerView model:(SWRefreshFooterViewModel *)model { SWRefreshFooterController* ctrl = [self new]; ctrl->_footerView = footerView; - ctrl->_footerModel = model; + ctrl.footerModel = model; return ctrl; } @@ -121,7 +122,7 @@ - (void)setScrollView:(UIScrollView *)scrollView { [self layoutFooterView]; } if (_footerModel) { - _footerModel.scrollView = [self isFooterVisible]?_scrollView:nil; + _footerModel.scrollView = (_scrollView && [self isFooterVisible])?_scrollView:nil; } } } @@ -130,10 +131,12 @@ - (void)setFooterModel:(__kindof SWRefreshFooterViewModel *)footerModel { if (_footerModel != footerModel) { if (_footerModel) { _footerModel.scrollView = nil; + [_footerModel removeObserver:self forKeyPath:@"state"]; } _footerModel = footerModel; if (_footerModel) { _footerModel.scrollView = [self isFooterVisible]?_scrollView:nil; + [_footerModel addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionOld context:@"state"]; } } } @@ -184,6 +187,12 @@ - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable i [self updateFooterViewFrame]; [self updateFooterVisible]; } + } else if (@"state" == context) { + SWRefreshState o = [change[NSKeyValueChangeOldKey] integerValue]; + SWRefreshState n = _footerModel.state; + if (_hideWhenNoMore && o != n && (o == SWRefreshStateNoMoreData || n == SWRefreshStateNoMoreData) ) { + [self updateFooterVisible]; + } } } diff --git a/SWRefresh/SWRefreshHeaderViewModel.m b/SWRefresh/SWRefreshHeaderViewModel.m index c5d6684..ae66bcd 100644 --- a/SWRefresh/SWRefreshHeaderViewModel.m +++ b/SWRefresh/SWRefreshHeaderViewModel.m @@ -19,8 +19,8 @@ - (void)unbindScrollView:(UIScrollView *)scrollView { - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change { CGPoint offset = self.scrollView.contentOffset; - UIEdgeInsets _scrollViewOriginInsets = self.scrollViewOriginInsets; if (self.state == SWRefreshStateRefreshing) { + UIEdgeInsets _scrollViewOriginInsets = self.scrollViewOriginInsets; if ( self.scrollView.dragging ) { // Keep header, inset 应该在 origin top inset 和 加上高度之前 UIEdgeInsets inset = self.scrollView.contentInset; @@ -34,13 +34,12 @@ - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change { return; } - // inset可能改变, 改为父类监听修改 - // _scrollViewOriginInsets = self.scrollView.contentInset; - // 刚好出现offset - CGFloat happendOffsetY = -_scrollViewOriginInsets.top; - + CGFloat happendOffsetY = [self happendOffsetY]; // 没达到临界点 - if ( happendOffsetY < offset.y ) return; + if ( happendOffsetY < offset.y ) { + if (self.pullingPercent > 0) { self.pullingPercent = 0; } + return; + } CGFloat pullingPercent = (happendOffsetY - offset.y) / _refreshThreshold; @@ -60,6 +59,20 @@ - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change { } } +/// 刚好出现offset +- (CGFloat)happendOffsetY { + // inset可能改变, 改为父类监听修改 + // _scrollViewOriginInsets = self.scrollView.contentInset; + UIEdgeInsets _scrollViewOriginInsets = self.scrollViewOriginInsets; + if (@available(iOS 11.0, *)) { + UIEdgeInsets c = self.scrollView.contentInset; + UIEdgeInsets adjust = self.scrollView.adjustedContentInset; + return -_scrollViewOriginInsets.top - (adjust.top - c.top); + } else { + return -_scrollViewOriginInsets.top; + } +} + - (void)changeFromState:(SWRefreshState)oldState to:(SWRefreshState)newState { NSAssert([NSThread isMainThread], @"should change state in main thread!"); if (!self.weakScrollView) {return;} diff --git a/SWRefreshExample/Base.lproj/Main.storyboard b/SWRefreshExample/Base.lproj/Main.storyboard index b489a96..dbb596a 100644 --- a/SWRefreshExample/Base.lproj/Main.storyboard +++ b/SWRefreshExample/Base.lproj/Main.storyboard @@ -1,8 +1,12 @@ - - + + + + + - - + + + @@ -10,7 +14,7 @@ - + @@ -30,9 +34,9 @@ - + - + diff --git a/SWRefreshExample/TableViewController.m b/SWRefreshExample/TableViewController.m index 6521826..a85a742 100644 --- a/SWRefreshExample/TableViewController.m +++ b/SWRefreshExample/TableViewController.m @@ -38,6 +38,10 @@ - (void)viewDidLoad { SWRefreshingBlock block = ^(SWRefreshViewModel* model){ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2* NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + if (weak_tableView.refreshFooterModel.state == SWRefreshStateNoMoreData) { + [weak_self.dataSource removeAllObjects]; + [weak_tableView.refreshFooterModel resetNoMoreData]; + } for (int i = 0; i < 3; ++i) { [weak_self.dataSource addObject:[NSDate date].description]; } @@ -61,6 +65,8 @@ - (void)viewDidLoad { }); }; tableView.refreshFooter = [SWRefreshFooterView footerWithRefreshingBlock:block]; + // comment this to see nomore state + tableView.refreshFooter.hideWhenNoMore = true; tableView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0); CGRect frame = tableView.bounds; @@ -72,6 +78,9 @@ - (void)viewDidLoad { insetTopLabel.textAlignment = NSTextAlignmentCenter; [tableView addSubview:insetTopLabel]; + // if (@available(iOS 11.0, *)) { + // tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + // } tableView.refreshHeader.headerOffset = 50; }