升级版本 解决三大问题:1.多控制器时候 切换导致秩序问题 2.通知命名重复冲突问题3.优化代码
QQ20200601-143648-HD.gif
结构
结构.png- HomePageVC 的子控制器homeParentVC、homeParentVC管理多个子控制器HomeSonVC
- HomePageVC的scrollView必须允许多手势
- HomeSonVC的scrollView可以不允许多手势、HomeSonVC继承BaseScrollViewVC即可
BaseScrollViewVC(直接继承即可)
.h
/**
1.解决多个VC通知发送影响问题
1.1 接受 baseScrollNotiName + 通知名 + baseScrollIndex HomePageListsItemVC+kNSGoTop+1 接受都是子控制器 一对一 (以前是一对多 父类控制器发送 很多子类接受)
1.1 发送通知 发送是可以用同一个名字 HomePageListsItemVC+KNSLeaveTop+all (多对一 所以父类控制器不怕发送多)
*/
#import "BaseVC.h"
NS_ASSUME_NONNULL_BEGIN
@interface BaseScrollViewVC : BaseVC
@property(nonatomic,strong)NSString *baseScrollNotiName;//多VC下滑动标记发通知
@property(nonatomic,assign)NSInteger baseScrollIndex;//多VC下滑动标记发通知
@property(nonatomic,assign)BOOL canScroll;//是否可以滚动 默认是不可滚动的 必须等父类控制器的通知
@property(strong,nonatomic)UIScrollView *currentScrollView;//通过scroll代理绑定当前滑动视图
@property(nonatomic,copy)void (^callBackScrollBlcok)(UIScrollView *scrollView);
@end
NS_ASSUME_NONNULL_END
.m
#import "BaseScrollViewVC.h"
@interface BaseScrollViewVC ()<UIGestureRecognizerDelegate,UIScrollViewDelegate>
@end
@implementation BaseScrollViewVC
- (void)viewDidLoad
{
[super viewDidLoad];
//子控制器视图到达顶部的通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(acceptMsg:) name:[NSString stringWithFormat:@"%@+%@+%ld",self.baseScrollNotiName,kNestingScrollGoTopNoti,self.baseScrollIndex] object:nil];
//这个千万不能加 要在主控制器先判断主控制器(如果HomePageVC)滑动状态
//self.canScroll = NO;
}
//接收信息,处理通知
- (void)acceptMsg:(NSNotification *)notification
{
//NSLog(@"子控制器接受goTop通知,%@",notification.name);
NSString *notificationName = notification.name;
if ([notificationName isEqualToString:[NSString stringWithFormat:@"%@+%@+%ld",self.baseScrollNotiName,kNestingScrollGoTopNoti,self.baseScrollIndex]])
{
self.canScroll = YES;
self.currentScrollView.showsVerticalScrollIndicator = YES;
}
}
#pragma mark - ScrollView代理
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!self.canScroll)
{
//不可以滑动 设置 CGPointZero 都很准在0.0000 没有因为上下滑动
[scrollView setContentOffset:CGPointZero];
}
CGFloat offsetY = scrollView.contentOffset.y;
if (offsetY < 0)
{
//这里发送离开通知...
//NSLog(@"子控制器发送leaveTop通知,%@",[NSString stringWithFormat:@"%@+%@+all",self.baseScrollNotiName,kNestingScrollLeaveTopNoti]);
[[NSNotificationCenter defaultCenter]postNotificationName:[NSString stringWithFormat:@"%@+%@+all",self.baseScrollNotiName,kNestingScrollLeaveTopNoti] object:nil];
[scrollView setContentOffset:CGPointZero];
self.canScroll = NO;
scrollView.showsVerticalScrollIndicator = NO;
}
_currentScrollView = scrollView;
//回调偏移量
!self.callBackScrollBlcok ?: self.callBackScrollBlcok (scrollView);
}
//处理左滑右滑,防止左滑返回上一界面
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// 首先判断otherGestureRecognizer是不是系统pop手势
if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")])
{
// 再判断系统手势的state是began还是fail,同时判断scrollView的位置是不是正好在最左边
if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.currentScrollView.contentOffset.x == 0)
{
return YES;
}
}
return NO;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
- 为了解决通知名字不重复,所以需要.h传入进来参数
- 临界点控制setContentOffset偏移量
- 一个block用于回调偏移量防止子类重写scrollViewDidScroll
- 子类继承控制器必须有UIScrollView子类并且设置代理不然.m里面scrollViewDidScroll不执行了
- 子类endRefresh记得提醒主控制器
HomePageVC
.h
#import "BaseVC.h"
NS_ASSUME_NONNULL_BEGIN
@interface HomePageVC : BaseVC
@property(nonatomic,assign,readonly)BOOL canScroll;
@end
NS_ASSUME_NONNULL_END
.m
#import "HomePageVC.h"
#import "HomeParentVC.h"
@interface HomePageVC ()<UITableViewDelegate,UITableViewDataSource>
@property(nonatomic,strong)BaseTableView *mainView;
@property(nonatomic,strong)HomeParentVC *managerVC;
//滑动属性
@property(nonatomic,assign)BOOL canScroll;
@property(nonatomic,assign)BOOL canMove;//临界点(大于等于临界点不能滑动NO,小于临界点可以滑动)
@property(nonatomic,assign)BOOL canMovePrevious;
@end
@implementation HomePageVC
#pragma mark - life生命区
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[Factory backAPPTabBarVC]changeSelectedIndex:0];
}
- (void)createProperty
{
self.canScroll = YES;
self.canMove = YES;
self.canMovePrevious = YES;
//监听
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(acceptMsg:) name:[NSString stringWithFormat:@"%@+%@+all",@"HomeSonVC",kNestingScrollLeaveTopNoti] object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(endRefresh) name:kNestingScrollEndRefreshNoti object:nil];
}
- (void)createUI
{
//临时头部
UIImageView *tableHeaderView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, 206*ADAPTER_WIDTH)];
tableHeaderView.backgroundColor = RedColor;
[tableHeaderView sd_setImageWithURL:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1590987737591&di=e0e922dae7fd800750e17753efe9bc05&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20190720%2F188eef713776424c933eaa2de61f9dbf.jpeg".wppURL];
tableHeaderView.clipsToBounds = YES;
self.mainView.tableHeaderView = tableHeaderView;
//添加刷新
WK(weakSelf)
self.mainView.mj_header = [BossHeaderView headerWithRefreshingBlock:^{
[weakSelf.managerVC refreshCurrentSonVC];
}];
}
- (void)endRefresh
{
[self.mainView.mj_header endRefreshing];
}
#pragma mark - UITableView代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = kColorBGTinyBlue;
[cell.contentView addSubview:self.managerVC.view];
return cell;
}
#pragma mark - 滑动代码
//接收信息,处理通知
- (void)acceptMsg:(NSNotification *)notification
{
//NSLog(@"%@",notification.name);
if ([notification.name isEqualToString:[NSString stringWithFormat:@"%@+%@+all",@"HomeSonVC",kNestingScrollLeaveTopNoti]]) {
//NSLog(@"主控制器接受:leaveTop通知");
self.canScroll = YES;
//这里处理已经创建的view 所有contentOffsetY 会0
[self.managerVC.childViewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//HomePageListsItemVC
if ([obj isKindOfClass:[BaseScrollViewVC class]]) {
if (obj.viewLoaded) {
BaseScrollViewVC *scrollVC = (BaseScrollViewVC *)obj;
[scrollVC.currentScrollView setContentOffset:CGPointZero];
scrollVC.canScroll = NO;
}
}
}];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//NSLog(@"%f,%f",scrollView.contentOffset.y,ceil(scrollView.contentOffset.y));
//最重要的就是 子视图滑动会影响主控制器视图 比如:子视图向下滑动 手势传递 自然contentOffsetY 会变大 子视图向上滑动 手势传递 自然contentOffsetY 会变小 从而影响临界点问题
CGFloat offset = scrollView.contentOffset.y + scrollView.contentInset.top;
CGFloat tableHeaderShowHeight = kStatusBarHeight + 30*ADAPTER_WIDTH;
CGFloat criticalPoint = self.mainView.tableHeaderView.height - tableHeaderShowHeight;
if (self.canScroll) {
self.canMovePrevious = self.canMove;
if (ceil(offset) >= ceil(criticalPoint)) {
[scrollView setContentOffset:CGPointMake(0, criticalPoint)];
self.canMove = NO;
} else {
self.canMove = YES;
//NSLog(@"向上移动");
}
if (self.canMove != self.canMovePrevious) {
if (self.canMove == NO && self.canMovePrevious == YES) {
//NSLog(@"不可以滑动 大于或等于临界点");
//发送通知 必须针对 当前的VC 不能一样
[[NSNotificationCenter defaultCenter]postNotificationName:[NSString stringWithFormat:@"%@+%@+%ld",@"HomeSonVC",kNestingScrollGoTopNoti,self.managerVC.currentIndex] object:nil];
_canScroll = NO;
}
if (self.canMove == YES && self.canMovePrevious == NO) {
//NSLog(@"可以滑动 小于临界点");
//[scrollView setContentOffset:CGPointMake(0, criticalPoint)];
}
}
} else {
[scrollView setContentOffset:CGPointMake(0, criticalPoint)];
}
}
#pragma mark - lazy懒加载
- (BaseTableView *)mainView
{
if (!_mainView) {
BaseTableView *tableView = [[BaseTableView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT - kCustomTabBarHeight) style:UITableViewStylePlain];
[self.view addSubview:tableView];
tableView.delegate = self;
tableView.dataSource = self;
tableView.tableFooterView = [UIView new];
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.backgroundColor = kColorBGTinyBlue;
if (@available(iOS 11.0, *))
{
tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
tableView.estimatedRowHeight = 0;
tableView.estimatedSectionFooterHeight = 0;
tableView.estimatedSectionHeaderHeight = 0;
}
else
{
self.automaticallyAdjustsScrollViewInsets = NO;
}
tableView.rowHeight = HEIGHT - kCustomTabBarHeight;
tableView.showsVerticalScrollIndicator = NO;
_mainView = tableView;
}
return _mainView;
}
- (HomeParentVC *)managerVC
{
if (!_managerVC) {
HomeParentVC *vc = [[HomeParentVC alloc]init];
CGFloat tableHeaderShowHeight = kStatusBarHeight + 30*ADAPTER_WIDTH;
vc.viewHeight = HEIGHT - kCustomTabBarHeight - tableHeaderShowHeight;
[self addChildViewController:vc];
_managerVC = vc;
}
return _managerVC;
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
@end
- 核心方法acceptMsg、scrollViewDidScroll
-
属性canScroll、canMove、canMovePrevious
3) image.png
1)默认canScroll、canMove、canMovePrevious都是YES可以滑动
2)将canMove赋值给canMovePrevious
HomeParentVC
.h
#import "BaseVC.h"
NS_ASSUME_NONNULL_BEGIN
@interface HomeParentVC : BaseVC
@property(nonatomic,assign)CGFloat viewHeight;
@property(nonatomic,assign)NSInteger jumIndex;
@property(nonatomic,assign,readonly)NSInteger currentIndex;//提供给发通知的
/**
刷新当前子控制器
*/
- (void)refreshCurrentSonVC;
@end
NS_ASSUME_NONNULL_END
.m
#import "HomeParentVC.h"
#import "HomeSonVC.h"
#import "BSTBitmapView.h"
#import "HomePageVC.h"
@interface HomeParentVC ()<UIScrollViewDelegate>
@property(nonatomic,strong)UIScrollView *titleBG;
@property(nonatomic,strong)UIScrollView *contentBG;
@property(nonatomic,strong)NSMutableArray<UILabel *> *titleBtnArrs;
@property(nonatomic,strong)UILabel *preLab;
@property(nonatomic,strong)UIView *selectedItemBottomLine;
//记录当前子控制器index
@property(nonatomic,assign)NSInteger currentIndex;
@end
@implementation HomeParentVC
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)createProperty
{
}
- (void)createUI
{
[self createContentBG];
[self createTitleBG];
}
#pragma mark - UI
- (void)createTitleBG
{
//准备滑动标题
NSMutableArray<NSString *> *nameArrs = [NSMutableArray array];
[nameArrs addObject:@"精选"];
[nameArrs addObject:@"排行榜"];
[nameArrs addObject:@"会逛超市"];
[nameArrs addObject:@"鸡蛋禽类"];
[nameArrs addObject:@"水果蔬菜"];
//titleBG
UIScrollView *titleBG = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, 42)];
[self.view addSubview:titleBG];
titleBG.backgroundColor = [UIColor whiteColor];
titleBG.showsVerticalScrollIndicator = NO;
titleBG.showsHorizontalScrollIndicator = NO;
//titleBG.delegate = self;
//titleBG.bounces = NO;
self.titleBG = titleBG;
//滑动小按钮下面的横线 提前创建 比小按钮早添加到titleBG
UIView *selectedItemBottomLine = [[UIView alloc]init];
[titleBG addSubview:selectedItemBottomLine];
selectedItemBottomLine.backgroundColor = RGB(252, 181, 111, 1);
self.selectedItemBottomLine = selectedItemBottomLine;
UITapGestureRecognizer *jumIndexTap;
CGFloat orinX = 13*ADAPTER_WIDTH,itemMargin = 25*ADAPTER_WIDTH;
//for循环布局
for (NSInteger index = 0; index < nameArrs.count; index ++) {
NSString *content = nameArrs[index];
CGFloat itemWidth = [content sizeWithFont:[UIFont systemFontOfSize:16*ADAPTER_WIDTH weight:UIFontWeightMedium]].width;
UILabel *lab = [[UILabel alloc]init];
[titleBG addSubview:lab];
lab.text = content;
lab.font = [UIFont systemFontOfSize:16*ADAPTER_WIDTH weight:UIFontWeightMedium];
lab.textColor = kColor48;
lab.frame = CGRectMake(orinX, 14, itemWidth, 17*ADAPTER_WIDTH);
orinX = index == (nameArrs.count - 1) ? (lab.right + 13*ADAPTER_WIDTH) : (lab.right + itemMargin);
//添加点击事件
lab.tag = index;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(clickItem:)];
lab.userInteractionEnabled = YES;
[lab addGestureRecognizer:tap];
//加入数组中
[self.titleBtnArrs addObject:lab];
if (index == self.jumIndex)
{
self.preLab = lab;
selectedItemBottomLine.frame = CGRectMake(lab.left+2, lab.bottom-4, lab.width-4, 4);
jumIndexTap = tap;//绑定要跳转的
}
}
titleBG.contentSize = CGSizeMake(orinX, 0);
//为什么在循环之外写呢 因为 头部没有创建完整 进行跳转 头部如果过长 会出现 标题不能居中问题
[self clickItem:jumIndexTap];
}
- (void)createContentBG
{
UIScrollView *contentBG = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 42, WIDTH, self.viewHeight - 42)];
[self.view addSubview:contentBG];
contentBG.backgroundColor = [UIColor whiteColor];
contentBG.showsVerticalScrollIndicator = NO;
contentBG.showsHorizontalScrollIndicator = NO;
contentBG.pagingEnabled = YES;
contentBG.bounces = NO;
contentBG.delegate = self;
self.contentBG = contentBG;
//添加控制器
HomeSonVC *vc = [[HomeSonVC alloc]init];
[self addChildViewController:vc];
HomeSonVC *vc1 = [[HomeSonVC alloc]init];
[self addChildViewController:vc1];
HomeSonVC *vc2 = [[HomeSonVC alloc]init];
[self addChildViewController:vc2];
HomeSonVC *vc3 = [[HomeSonVC alloc]init];
[self addChildViewController:vc3];
HomeSonVC *vc4 = [[HomeSonVC alloc]init];
[self addChildViewController:vc4];
//这里可以添加VC的回调block之类的
//扩大滑动范围
contentBG.contentSize = CGSizeMake(WIDTH * self.childViewControllers.count, 0);
for (NSInteger index = 0; index < self.childViewControllers.count; index ++)
{
BSTBitmapView *bitmapView = [[BSTBitmapView alloc]initWithFrame:CGRectMake(index*WIDTH, 0, WIDTH, contentBG.height)];
[self.contentBG addSubview:bitmapView];
bitmapView.type = BitmapViewTypeLoading;
bitmapView.tag = 100+index;
}
}
#pragma mark - 点击事件
- (void)clickItem:(UITapGestureRecognizer *)sender
{
//如果animated 是YES 会走scrollView 多次 2个界面会好看些
[self.contentBG setContentOffset:CGPointMake(sender.view.tag * WIDTH, 0) animated:NO];
//处理控制器
[self setUpSubController:sender.view.tag];
//处理头部title
[self refreshTitleLab:self.titleBtnArrs[sender.view.tag]];
}
#pragma mark - SCrollView代理方法
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger index = scrollView.contentOffset.x / WIDTH;
//处理控制器
[self setUpSubController:index];
//处理头部title
[self refreshTitleLab:self.titleBtnArrs[index]];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSInteger index = scrollView.contentOffset.x / WIDTH;
CGFloat tmpOffsetX = scrollView.contentOffset.x / WIDTH;
CGFloat scaleRight = tmpOffsetX - index;
CGFloat scaleLeft = 1 - scaleRight;
if (index + 1 <= self.titleBtnArrs.count - 1)
{
//NSLog(@"%ld,%f,%f",index,scaleRight,scaleLeft);
//self.selectedItemBottomLine.frame = CGRectMake(currentLab.left+2, self.selectedItemBottomLine.top, self.selectedItemBottomLine.width, self.selectedItemBottomLine.height);
UILabel *leftLab = self.titleBtnArrs[index];
UILabel *rightLab = self.titleBtnArrs[index+1];
if (scaleRight == 0)
{
//NSLog(@"到达临界值...");
return;
}
if (self.currentIndex == index)
{
//NSLog(@"向右");
self.selectedItemBottomLine.frame = CGRectMake(leftLab.left+2, self.selectedItemBottomLine.top, leftLab.width-4+(scaleRight*(rightLab.left-leftLab.right)), self.selectedItemBottomLine.height);
}
else
{
//NSLog(@"向左");
self.selectedItemBottomLine.frame = CGRectMake(rightLab.left+2-(scaleLeft*(rightLab.left-leftLab.right)), self.selectedItemBottomLine.top, leftLab.width-4+(scaleLeft*(rightLab.left-leftLab.right)), self.selectedItemBottomLine.height);
}
}
}
#pragma mark - 添加子控制器视图
- (void)setUpSubController:(NSInteger)index
{
self.currentIndex = index;
HomeSonVC *vc = self.childViewControllers[index];
//做一些 vc的初始化
vc.viewHeight = self.contentBG.height;
vc.baseScrollIndex = index;
vc.baseScrollNotiName = @"HomeSonVC";
//判断父类控制器 是否可以滑动
if ([self.parentViewController isMemberOfClass:[HomePageVC class]]) {
HomePageVC *parentVC = (HomePageVC *)self.parentViewController;
vc.canScroll = !parentVC.canScroll;
}
if (vc.view.superview)
{
return;
}
vc.view.frame = CGRectMake(index *WIDTH, 0, WIDTH, self.contentBG.height);
[self.contentBG addSubview:vc.view];
//清除占位图
BSTBitmapView *bitMapView = [self.contentBG viewWithTag:100+index];
if (bitMapView != nil)
{
[bitMapView removeFromSuperview];
}
}
#pragma mark - 矫正滑动标题的居中问题
- (void)refreshTitleLab:(UILabel *)currentLab
{
self.preLab.textColor = kColor48;
self.preLab = currentLab;
[UIView animateWithDuration:0.2 delay:0 usingSpringWithDamping:0.6 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.selectedItemBottomLine.frame = CGRectMake(currentLab.left+2, self.selectedItemBottomLine.top, currentLab.width-4, self.selectedItemBottomLine.height);
} completion:^(BOOL finished) {
}];
//标题居中
//NSLog(@"设置居中...");
CGFloat offsetX = currentLab.center.x - (self.titleBG.width *0.5);
if (offsetX < 0)
{
offsetX = 0;
}
//如果针对 标签数量小 滑动范围小则出现问题 所有判断一下
if (self.titleBG.contentSize.width > self.titleBG.width) {
CGFloat maxOffsetX = self.titleBG.contentSize.width - self.titleBG.width;
if (offsetX > maxOffsetX)
{
offsetX = maxOffsetX;
}
}
//NSLog(@"offsetX:%f",offsetX);
[self.titleBG setContentOffset:CGPointMake(offsetX, 0) animated:YES];
}
#pragma mark - 公开方法
- (void)refreshCurrentSonVC
{
if (self.childViewControllers.count == 0) {
[[NSNotificationCenter defaultCenter]postNotificationName:kNestingScrollEndRefreshNoti object:nil];
return;
}
HomeSonVC *vc = self.childViewControllers[self.currentIndex];
[vc loadNewData];
}
#pragma mark - Lazy懒加载区域
- (NSMutableArray<UILabel *> *)titleBtnArrs
{
if (!_titleBtnArrs)
{
_titleBtnArrs = [NSMutableArray array];
}
return _titleBtnArrs;
}
@end
- @property(nonatomic,assign,readonly)NSInteger currentIndex;//提供给发通知的
- setUpSubController方法中 给VC传入通知所需属性
#pragma mark - 添加子控制器视图
- (void)setUpSubController:(NSInteger)index
{
self.currentIndex = index;
HomeSonVC *vc = self.childViewControllers[index];
//做一些 vc的初始化
vc.viewHeight = self.contentBG.height;
vc.baseScrollIndex = index;
vc.baseScrollNotiName = @"HomeSonVC";
//判断父类控制器 是否可以滑动
if ([self.parentViewController isMemberOfClass:[HomePageVC class]]) {
HomePageVC *parentVC = (HomePageVC *)self.parentViewController;
vc.canScroll = !parentVC.canScroll;
}
if (vc.view.superview)
{
return;
}
vc.view.frame = CGRectMake(index *WIDTH, 0, WIDTH, self.contentBG.height);
[self.contentBG addSubview:vc.view];
//清除占位图
BSTBitmapView *bitMapView = [self.contentBG viewWithTag:100+index];
if (bitMapView != nil)
{
[bitMapView removeFromSuperview];
}
}
如果还有一个头部伸缩在criticalPoint 进行修改
QQ20200601-173204-HD.gif- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//NSLog(@"%f,%f",scrollView.contentOffset.y,ceil(scrollView.contentOffset.y));
//最重要的就是 子视图滑动会影响主控制器视图 比如:子视图向下滑动 手势传递 自然contentOffsetY 会变大 子视图向上滑动 手势传递 自然contentOffsetY 会变小 从而影响临界点问题
CGFloat offset = scrollView.contentOffset.y + scrollView.contentInset.top;
//伸缩
if (offset <= 0) {
self.flexView.top = 0;
self.flexView.height = fabs(offset) + kContentInsetTop;
CGFloat percent = self.flexView.height / kContentInsetTop;
//宽度整体扩大
self.flexView.width = WIDTH * percent;
self.flexView.left = - (WIDTH * (percent - 1) * 0.5);
} else {
CGFloat flexShowHeight = kStatusBarHeight + 30*ADAPTER_WIDTH;
CGFloat flexCriticalPoint = kContentInsetTop - flexShowHeight;
CGFloat minOffset = MIN(offset, flexCriticalPoint);
self.flexView.top = -minOffset;
self.flexView.height = kContentInsetTop;
//宽度整体恢复
self.flexView.width = WIDTH;
self.flexView.left = 0;
}
//头部
CGFloat tableHeaderShowHeight = kStatusBarHeight + 50*ADAPTER_WIDTH;
CGFloat criticalPoint = self.mainView.tableHeaderView.height - tableHeaderShowHeight + kContentInsetTop;
if (self.canScroll) {
self.canMovePrevious = self.canMove;
if (ceil(offset) >= ceil(criticalPoint)) {
[scrollView setContentOffset:CGPointMake(0, criticalPoint - kContentInsetTop)];
self.canMove = NO;
} else {
self.canMove = YES;
//NSLog(@"向上移动");
}
if (self.canMove != self.canMovePrevious) {
if (self.canMove == NO && self.canMovePrevious == YES) {
//NSLog(@"不可以滑动 大于或等于临界点");
//发送通知 必须针对 当前的VC 不能一样
[[NSNotificationCenter defaultCenter]postNotificationName:[NSString stringWithFormat:@"%@+%@+%ld",@"HomeSonVC",kNestingScrollGoTopNoti,self.managerVC.currentIndex] object:nil];
_canScroll = NO;
}
if (self.canMove == YES && self.canMovePrevious == NO) {
//NSLog(@"可以滑动 小于临界点");
//[scrollView setContentOffset:CGPointMake(0, criticalPoint)];
}
}
} else {
[scrollView setContentOffset:CGPointMake(0, criticalPoint - kContentInsetTop)];
}
}
bug汇总
如果悬停和managerVC的子控制器都是靠着网络请求获取 需要cell代理方法中添加判断是否网络请求成功 还有就是rowHeight在懒加载是0 需要重新赋值
崩溃闪退-滑动问题.png
-
防止一直转
防止一直转.png
网友评论