在仿微博主页时,对其做了小小的改动,效果怎样,看大家项目的需求了:
分段控制器用的是YUSegment;
头部下拉放大使用的HFStretchableTableHeaderView,这个虽然很久了,但确实很实用;
由于是demo,所以使用的是自带的UIPageViewController,对于这个控件的一些缺陷,大家勿喷,根据自己需求更换即可;
在我的demo中比较重要的一个方法:
///允许同时识别多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
由于我的主控制器使用的是UItableView,在TableView的一个cell里放了三个子控制器,来实现的,实现这个效果有很多种方法,我这个其一,三个子控制器都是继承一个BaseTableViewController,主要是方便用来判断该控制器是否可以滑动:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
//下拉放大 必须实现
[_stretchableTableHeaderView scrollViewDidScroll:scrollView];
//计算导航栏的透明度
UIImage *image = [UIImage imageNamed:@"pc_bg"];
CGFloat minAlphaOffset = 0;
CGFloat maxAlphaOffset = image.size.height-64;
CGFloat offset = scrollView.contentOffset.y;
CGFloat alpha = (offset - minAlphaOffset) / (maxAlphaOffset - minAlphaOffset);
_barImageView.alpha = alpha;
//根据导航栏透明度设置title
if (alpha > 0.5) {
self.title = @"name";
} else {
self.title = @"";
}
//子控制器和主控制器之间的滑动状态切换
CGFloat tabOffsetY = [_tableView rectForSection:0].origin.y-64;
if (scrollView.contentOffset.y >= tabOffsetY) {
scrollView.contentOffset = CGPointMake(0, tabOffsetY);
if (_canScroll) {
//通知子控制器可以滑动了,其实这个通知是可以省掉了
[[NSNotificationCenter defaultCenter] postNotificationName:@"kScrollToTopNtf" object:@1];
_canScroll = NO;
//在cell中告诉子控制器可以滑动了
self.contentCell.canScroll = YES;
}
} else {
if (!_canScroll) {
scrollView.contentOffset = CGPointMake(0, tabOffsetY);
}
}
}
另外解决pageView左右滑动时,会带动主控制器上下滑动,我的实现原理是监听pageView中的手势:
///pageView
- (void)customPageView {
NSDictionary *option = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:UIPageViewControllerSpineLocationMin] forKey:UIPageViewControllerOptionSpineLocationKey];
self.pageViewCtrl = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:option];
self.pageViewCtrl.dataSource = self;
self.pageViewCtrl.delegate = self;
PersonalLeftViewController *ctrl1 = [[PersonalLeftViewController alloc] init];
PersonalMiddleViewController *ctrl2 = [[PersonalMiddleViewController alloc] init];
PersonalRightViewController *ctrl3 = [[PersonalRightViewController alloc] init];
self.dataArray = @[ctrl1,ctrl2,ctrl3].mutableCopy;
[self.pageViewCtrl setViewControllers:@[self.dataArray[0]]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
[self.contentView addSubview:self.pageViewCtrl.view];
for (UIView *view in self.pageViewCtrl.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
//监听拖动手势
[view addObserver:self
forKeyPath:@"panGestureRecognizer.state"
options:NSKeyValueObservingOptionNew
context:nil];
}
}
[self.pageViewCtrl.view mas_makeConstraints:^(MASConstraintMaker* make) {
make.edges.equalTo(self.contentView);
}];
}
//监听拖拽手势的回调
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context {
if (((UIScrollView *)object).panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
NSLog(@"bottomSView 滑动了,让主控制器不允许滑动");
[[NSNotificationCenter defaultCenter] postNotificationName:@"PageViewGestureState" object:@"changed"];
} else if (((UIScrollView *)object).panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
NSLog(@"结束拖拽");
[[NSNotificationCenter defaultCenter] postNotificationName:@"PageViewGestureState" object:@"ended"];
}
}
重要的部分就这么多,其实很简单,只是我写博客的时间不长,写的有点乱,还是接上代码demo吧:
demo:https://github.com/hkjin/PersonalHomePageDemo
效果图
下面接一个朋友对于导航栏渐变做的方案,当然啦,对于导航渐变大家应该有很多的解决方案,我个人觉得这位朋友的方案不错,贴出来让大家参考,感谢@李乾坤David
下面贴出他对导航处理的代码:@Liqiankun
在后续JOIN项目中,重新写了一个类(https://www.jianshu.com/p/8e6dfb547061),这个类比这个方法要好很多,也简单很多。。。