为什么用一丁点,因为工作原因,单纯只是了解并实现了一个初步效果,显得很low,并没有专门去优化过,也没有什么太过复杂的代码,不过需要一些计算,脑袋大了一圈,谁让自己不好好学数学呢,算!!!
首先页面布局是一个segment内部的controller包含一个scrollview,scrollview内部还是一个segment,segment内部的controller又带有tableview,听起来有点乱,说实话做起来也乱,水平低微,我很抱歉。先看看实现的效果吧![]()
这是最终的实现效果,界面比较low,哈哈
首先segment都用的wmpagecontroller,不用去考虑左右滑动带来的滑动冲突,点赞
其次就是当滚动的时候,要获取tableview滚动的变量,并传给上一层scrollview去做计算,这里具体我也忘了看的谁的博客了,感谢不知名的博主给了我想法,否则我还是一脸懵逼,子级视图的代码如下:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat offsetDifference = scrollView.contentOffset.y - self.lastContentOffset.y;
// 滚动时发出通知
[[NSNotificationCenter defaultCenter] postNotificationName:ChildScrollViewDidScrollNSNotification object:nil userInfo:@{@"scrollingScrollView":scrollView,@"offsetDifference":@(offsetDifference)}];
self.lastContentOffset = scrollView.contentOffset;
}
对,你没看错,就这么多,子级视图也并不需要太多额外的操作,只要负责把滚动量传回去就可以了,当然是当前滚动位置与上一次滚动位置的差值,如果有需要下拉刷新上拉加载的可以在要刷新的位置自行加一个通知,父级收到通知禁止滚动或打开滚动,详情见demo,就不赘述了
父级需要做的计算有点繁杂,首先要确定菜单要悬浮的位置,确定好位置后在父级的滚动代理里直接写好
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
self.viewMenu.frame =CGRectMake(SCREEN_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT-44-SafeAreaTopHeight-TabbarHeight-(56-SafeAreaTopHeight- self.tableView.contentOffset.y));
if (scrollView.contentOffset.y<=(-SafeAreaTopHeight-headMenuHeight)) {
[scrollView setContentOffset:CGPointMake(0, (-SafeAreaTopHeight-headMenuHeight))];
}
if (self.tableView.contentOffset.y>=(kHeaderViewH-headMenuHeight-SafeAreaTopHeight-7)) {
[self.tableView setContentOffset:CGPointMake(0, kHeaderViewH-headMenuHeight-SafeAreaTopHeight-7)];
}
[self changeColorWithOffsetY:self.tableView.contentOffset.y];
}
里面有些参数有点乱,大体是这么个意思
其次,就是子级视图发来的通知了
• (void)subScrollViewDidScroll:(NSNotification *)noti {
// 取出当前正在滑动的tableView
UIScrollView *scrollingScrollView = noti.userInfo[@"scrollingScrollView"];
CGFloat offsetDifference = [noti.userInfo[@"offsetDifference"] floatValue];
self.contentDistance = offsetDifference;
BusinessCircleListViewController *baseVc = self.arrControllers[self.pageController.selectIndex];
if (scrollingScrollView == baseVc.scrollView && baseVc.isFirstViewLoaded == NO) {
if (offsetDifference > 0 && scrollingScrollView.contentOffset.y> 0) {
if (self.tableView.contentOffset.y<(kHeaderViewH-headMenuHeight-SafeAreaTopHeight-7)) {
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y+offsetDifference)];
[baseVc.scrollView setContentOffset:CGPointMake(0, 0)];
}else{
[self.tableView setContentOffset:CGPointMake(0, kHeaderViewH-headMenuHeight-SafeAreaTopHeight-7)];
}
} else { // 往下移
if (self.tableView.contentOffset.y>(-SafeAreaTopHeight-headMenuHeight)) {
if (scrollingScrollView.contentOffset.y<=0) {
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y+offsetDifference)];
[baseVc.scrollView setContentOffset:CGPointMake(0, 0)];
}
}else{
[self.tableView setContentOffset:CGPointMake(0, (-SafeAreaTopHeight-headMenuHeight))];
}
}
}
[self changeColorWithOffsetY:self.tableView.contentOffset.y];
baseVc.isFirstViewLoaded = NO;
}
有点乱,具体的思路就是通过子级发送的滚动量的正负来确定滚动方向,然后将值加到父级的scrollview的contentoffset,让子级不滚动,父级来代替子级滚动,当父级滚动到一定值,即之前确定的菜单浮动的位置,父级停止滚动,子级视图开始滚动,这个限制是对父级限制,但是子级和父级不能同时滚动,嗯,我乱了,再加上父级下面还有一菜单,我悟了,数学是个好东西,demo的话待我整理一下再发。
OK,在下滚了
我胡了,代码传哪都传不上去,我胡了,度盘凑合一下