iOS 仿简书个人中心或者贴吧
先看效果图:
仿简书个人首页.gif参考文章:[实现简书个人中心UI效果]
(http://www.jianshu.com/p/d21189d9224b) 这篇文章已经介绍的很好了。很早就想实现类似的效果,看了一些效果,还是觉得他的思路好一点。对,你看到的都是假象.
首先需要设置
self.extendedLayoutIncludesOpaqueBars = YES; self.automaticallyAdjustsScrollViewInsets = NO;
这两行代码可以清除系统对UIScrollview
以及它的子类的一些设置,比如向下偏移64个像素等等,可以保证导航栏为透明的情况下起点仍然从左上角开始。
以上面的图为例,先设置好层级关系。
1、首先当前View
添加一个scrollview
,设置_mainScrollView.contentSize = CGSizeMake(3 *Device_Width,0 );
2、当前View
添加自定义header
。
3、当前View
添加分段控制器。
4、当前控制器添加三个子控制器,然后把是三个子控制的view
添加到mainScrollView
上。
5、子控制器的设置:子控制器里的tableview
添加统一的header
,header
的高度为分段控制器的高度+自定义header
的高度,这样在滑动mainScrollView
的时候分段控制器和自定义header
会盖住tableview
的header
,做成一个tableview
滑动的时候共用一个header
。
vc.headerH = self.segmentView.bottom - self.customHeader.y +1; //把外面自定义的header高度和 分段控制器的高度传入 ,做一个虚拟的header
需要处理的地方:
1、在下拉tableview
的时候,做到上面两部分跟随滑动,操作的还是contentOffsetY
。
2、在上滑动tableview的时候我们需要设置上面两部分跟随上移,然后在临界点的时候固定分段控制器的高度。就可以初步实现类似的效果。这个临界点的高度其实就是自定义header的高度。
3、接下来需要处理一些细节。
假定已经确定了临界点,我们需要处理几个细节:
1、小于临界点的时候我们需要保证三个子控制器的contentOffset高度保持一致
if (contentOffsetY < self.customHeader.height) {
[self.childViewControllers enumerateObjectsUsingBlock:^(__kindof LXTestBaseController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj.tableView.contentOffset.y != contentOffsetY) {
obj.tableView.contentOffset = tableview.contentOffset;
}
}];
2、在拖拽tableview
的时候我们需要获得三个子控制器中的tableview
最大的contentOffset
,设置contentOffset
>临界点的时候,统一设置tableview
的contentOffset
为临界点,也就是自定义header的高度。
好了基本的分析已经结束,关于头像放缩,原谅我太懒,直接拿来用了。
最核心的地方:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"contentOffset"]) {
UITableView *tableview = object;
CGFloat contentOffsetY = tableview.contentOffset.y;
//临界点是 自定义header的高度,这样我们就可以在滑动tableview的时候单独把分段控制器固定在上面。小于这个高度的时候我们需要把三个tableview的高度同步一下
if (contentOffsetY < self.customHeader.height) {
[self.childViewControllers enumerateObjectsUsingBlock:^(__kindof LXTestBaseController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj.tableView.contentOffset.y != contentOffsetY) {
obj.tableView.contentOffset = tableview.contentOffset;
}
}];
NSLog(@"%f",contentOffsetY);
self.customHeader.y = NAVH - contentOffsetY; //原始的y坐标 - 现在的偏移量
self.segmentView.y = self.customHeader.bottom;
}else{
self.customHeader.y = NAVH - self.customHeader.height; //固定y 坐标,
self.segmentView.y = self.customHeader.bottom;
}
// 处理顶部头像
CGFloat scale = tableview.contentOffset.y / 80;
// 如果大于80,==1,小于0,==0
if (tableview.contentOffset.y > 80) {
scale = 1;
} else if (tableview.contentOffset.y <= 0) {
scale = 0;
}
[self.avatarView setupScale:scale];
}
}
demo 地址:仿简书贴吧UI